我正在使用ModelMapper通过REST/API Spring微服务将DTOMap到数据库实体,在更新对子实体的引用时遇到了一个问题。在我的服务实现中,我首先使用JPA/Hibernate获取实体,将其添加到持久性上下文。子属性被急切地获取,因此整个实体对象被附加。一旦我拥有了实体,我正在使用ModelMapper用DTO更新它。我有一个ModelMapper配置,它定义了DTO上的ID到子实体上的ID的Map。初始创建工作正常,但如果子实体已经与父实体关联,并且我试图更新ID,Hibernate的抱怨是正确的,所以我改变了一个示例的标识符。我只关心引用,我没有通过这个更新来更新Dormitory实体上的任何数据。
这些实体并不完全是我正在使用的实体,但我尝试用它们来说明。假设我有一个学生实体,它与宿舍相关联。在数据库中,它与Student #123关联的是Dormitory #456。我传入的DTO将该关联更改为Dormitory #789。
public class Student {
@Id
@Column(name = "STUDENT_ID")
private Long studentID;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "DORMITORY_ID")
private Dormitory dormitory;
... getters and setters
}
public class Dormitory {
@Id
@Column(name = "DORMITORY_ID")
private Long dormitoryID;
@Column(name = "DORMITORY_NAME")
private String dormitoryName;
... getters and setters
}
public class StudentDTO {
private Long studentID;
private Long dormitoryID;
... getters and setters
}
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentRepository studentRepo;
@Autowired
ModelMapper modelMapper;
public void updateStudent(StudentDTO studentDTO) {
Student studentToUpdate = studentRepo.findById(studentDTO.getStudentID());
studentToUpdate.setDormitory(null); // Doing this works but doesn't seem right.
modelMapper.map(studentDTO, student)
studentRepo.saveAndFlush(student);
}
}
public class ModelMapperConfig {
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setDeepCopyEnabled(true);
PropertyMap<StudentDTO, Student> map = new PropertyMap<StudentDTO, Student>() {
protected void configure() {
map(source.getDormitoryID(), destination.getDormitory().getDormitoryID());
}
};
modelMapper.addMappings(map)
}
}
如果我在MapDTO之前将父实体上的子实体置为空,则会正常工作,因为新实体随后会通过ModelMapper创建。但这似乎不是正确的方法,我认为我做错了什么。
1条答案
按热度按时间icnyk63a1#
我对ModelMapper了解不多,但从您的描述来看,简单的JavaBeanMap器对于您的用例来说是远远不够的,我认为这是一个完美的Blaze-Persistence实体视图用例。
我创建这个库是为了允许在JPA模型和定制接口或抽象类定义的模型之间进行简单的Map,就像SpringDataProjectionson类固醇一样。(域模型)并Map属性(getters)Map到实体模型。然后,您可以基于该Map获取数据或将其刷新回来,并且库负责如何以最有效的方式刷新它的细节。
使用Blaze-Persistence Entity-Views时,您的用例的DTO模型可能如下所示:
查询就是将实体视图应用到查询中,最简单的查询就是按id查询。
StudentDto a = entityViewManager.find(entityManager, StudentDto.class, id);
Spring Data 集成允许您像使用Spring Data 投影一样使用它:www.example.comhttps://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
还允许您简单地刷新数据
最好的部分是,它只获取实际需要的状态!