Java - 使用循环依赖关系映射 DTO

标签 java design-patterns circular-dependency

当前正在设置经典映射器,将实体转换为 DTO。 一些实体(以及 DTO)相互引用(在特定的 JPA 实体定义之后)。

比方说:

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
}

有了这样的循环依赖,我必须像这样设置映射器:

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;
   }

轻松避免这种情况的一种方法是在 PersonMapper 或 StateMapper 中创建一个新方法,并使其不映射人员或状态。但我想知道是否有已知的设计模式或更通用的方法来做到这一点?

谢谢

最佳答案

唯一的方法是先构建一侧:

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;
  }
}

其他一切都会使用一些 Reference<State>喜欢数据结构,但我认为那不值得。您还可以通过删除一侧并关联 Person 来打破循环依赖关系。到其States需要时或存储 Map<State, List<Person>>在另一个层面上。但我仍然更喜欢文章开头概述的方法。

旁注:也许可以尝试 datus (免责声明:我是作者)并看看它是否适合您的其他转换任务并简化您的工作:)

关于Java - 使用循环依赖关系映射 DTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56329292/

相关文章:

java - 监听OPUS编码流

java - 优化 HibernateTemplate 的数据插入

Java iOS MDM : APNs Certificate UID changes

没有自动隐藏的 JavaFX MenuItem

user-interface - GUI架构设计资源?

ruby-on-rails-4 - 异常 : "load_missing_constant Circular dependency detected while autoloading constant" in Rails

c++ - C2061 - 循环依赖

java - 如何覆盖子类中的 @Autowired 属性

functional-programming - or-like feature in case … of statement?或者更通用的模式?

node.js - Nodejs Express 中的错误 : Converting circular structure to JSON --> starting at object with constructor 'Topology' | property 's' -> object with . ...