Currently settings up classic mappers, converting Entities to DTOs. Some of the entities (and thus DTOs) reference each other (after specific JPA entity definition).
Let's say:
public class Person {
private String name;
private List<State> states; // All states with this person
// Getters & Setters
}
public class State {
private String name;
private List<Person> persons; // All persons with this state
// Getters & Setters
}
With such circular dependencies I have to set up mappers like so:
public class PersonMapper {
public PersonDTO toDTO(Person p) { // not null
PersonDTO dto = new PersonDTO();
dto.setName(p.getName());
dto.setStates(p.States().stream().map(stateMapper::toDTO).collect(Collectors.toList());
return dto;
}
public class StateMapper {
public StateDTO toDTO(State s) { // not null
StateDTO dto = new StateDTO();
dto.setName(s.getName());
dto.setPersons(s.getPersons().stream().map(personMapper::toDTO).collect(Collectors.toList());
return dto;
}
One way to easily avoid this is to create a new method in PersonMapper or StateMapper and make it NOT map the persons or states. But I was wondering if there was a known design pattern or a more generic way of doing this?
Thanks
The only way is to construct one side first:
public class PersonMapper {
public PersonDTO toDTO(Person p) { // not null
PersonDTO dto = new PersonDTO();
dto.setName(p.getName());
dto.setStates(new ArrayList<>());
states.forEach(state -> state.getPersons().add(dto)) //todo: uniqueness check
return dto;
}
}
public class StateMapper {
//todo: maybe Person.name is better than the whole Person object in the map
public StateDTO toDTO(State s, Map<Person, PersonDTO> personMapping) {
StateDTO dto = new StateDTO();
dto.setName(s.getName());
List<PersonDTO> persons = s.getPersons().stream().map(personMapping::get)
.collect(Collectors.toList();
persons.forEach(p -> p.getStates().add(dto)) //todo: uniqueness check for states or use a set
dto.setPersons(persons);
return dto;
}
}
Everything else would use some Reference<State>
like data structure but I don't think thats worth it. You could also break the circular dependency by removing one side and correlate a Person
to its States
when needed or store a Map<State, List<Person>>
on another level. But I still prefer the approach outlined at the start of my post.
On a side-note: Maybe try datus (disclaimer: I am the author) and see if it fits your other conversion tasks and ease your work :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.