У меня есть двунаправленное сопоставление.
Когда я пытаюсь получить все категории из БД, все работает нормально. и когда я пытаюсь сопоставить то же самое с DTO для объекта с помощью mapstruct, я получаю ошибку ниже. Я пытался использовать CycleAvoidingMappingContext, но мне это не помогло. Я не хочу использовать атрибут игнорирования.
UserEntity
@Entity
@Table(name = "users")
@Getter
@Setter
@NoArgsConstructor
public class User extends BaseEntity {
private String username;
private String password;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "customer_id", referencedColumnName = "id")
private Customer customer;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "employee_id", referencedColumnName = "id")
private Employee employee;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "venue_id", referencedColumnName = "id")
private Venue venue;
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
Employee Entity
@Entity
@Table(name = "employee")
@Getter
@Setter
@NoArgsConstructor
public class Employee extends BaseEntity {
private String name;
private LocalDateTime closeHour;
private LocalDateTime openHour;
private Long phoneNumber;
@ManyToOne
private Venue venue;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "employee_sherbime",
joinColumns = @JoinColumn(name = "employee_id"),
inverseJoinColumns = @JoinColumn(name = "sherbime_id"))
private Set<Sherbime> employeeSherbime = new HashSet<>();
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
public void setUser(User user) {
if (user != null) {
user.setEmployee(this);
}
this.user = user;
}
}
EmployeMapper
@Mapper(componentModel = "spring", uses = {VenueMapper.class, SherbimeMapper.class, UserMapper.class})
public interface EmployeeMapper extends EntityMapper<EmployeeDTO, Employee> {
@Mapping(source = "venue", target = "venue")
@Mapping(source = "employeeSherbime", target = "employeeSherbime")
@Mapping(source = "user", target = "user")
EmployeeDTO toDto(Employee employee, @Context CycleAvoidingMappingContext context);
@Mapping(source = "venue", target = "venue")
@Mapping(source = "employeeSherbime", target = "employeeSherbime")
@Mapping(source = "user", target = "user")
Employee toEntity(EmployeeDTO employeeDTO, @Context CycleAvoidingMappingContext context);
}
CycleAvoidingMappingContext
public class CycleAvoidingMappingContext {
private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
@BeforeMapping
public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
return (T) knownInstances.get( source );
}
@BeforeMapping
public void storeMappedInstance(Object source, @MappingTarget Object target) {
knownInstances.put( source, target );
}
}
EmployeeServiceImpl
@Service
public class EmployeeServiceImpl implements EmployeeService {
private final Logger logger = LogManager.getLogger(EmployeeServiceImpl.class);
private final EmployeeRepository employeeRepository;
private final EmployeeMapper employeeMapper;
public EmployeeServiceImpl(EmployeeRepository employeeRepository, EmployeeMapper employeeMapper) {
this.employeeRepository = employeeRepository;
this.employeeMapper = employeeMapper;
}
@Override
public EmployeeDTO save(EmployeeDTO employeeDTO) {
logger.info("Request to save Employee : {}", employeeDTO);
Employee employee = employeeMapper.toEntity(employeeDTO, new CycleAvoidingMappingContext());
employee = employeeRepository.save(employee);
return employeeMapper.toDto(employee, new CycleAvoidingMappingContext());
}
Ошибка
java.lang.StackOverflowError: null
at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:168) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at com.pimp.service.mapper.EmployeeMapperImpl.sherbimeSetToSherbimeDTOSet(EmployeeMapperImpl.java:182) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:70) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:15) ~[classes/:na]
at com.pimp.service.mapper.UserMapperImpl.toDto(UserMapperImpl.java:63) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:71) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:15) ~[classes/:na]
at com.pimp.service.mapper.UserMapperImpl.toDto(UserMapperImpl.java:63) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:71) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:15) ~[classes/:na]
at com.pimp.service.mapper.UserMapperImpl.toDto(UserMapperImpl.java:63) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:71) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:15) ~[classes/:na]
at com.pimp.service.mapper.UserMapperImpl.toDto(UserMapperImpl.java:63) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:71) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:15) ~[classes/:na]
at com.pimp.service.mapper.UserMapperImpl.toDto(UserMapperImpl.java:63) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:71) ~[classes/:na]
at com.pimp.service.mapper.EmployeeMapperImpl.toDto(EmployeeMapperImpl.java:15) ~[classes/:na]