【发布时间】:2020-07-15 13:07:04
【问题描述】:
我正在用SpringBoot 2.2.6 重写一个大项目,但遇到了问题。
在旧项目(纯ejb)中更新复杂实体时,代码从DTO's构建entity如下:
public Entity dtoToEntity(DTO dto) {
Entity entity = new Entity();
entity.setId(dto.getID());
// ecc...
// ecc...
entity.setSubEntity(dto.getSubEntity() != null ? new SubEntity(dto.getSubEntity().getId() : null);
// and so on
}
重要的部分是与子实体相关的部分!在制作了这样的映射后,旧项目调用:
EntityManager.merge(entity);
我认为通过合并调用,如果在数据库中存在具有指定 id 和 其他已验证的字段的子实体,则其他字段保持有效并且不会设置为 null,因为它们没有在映射。
但是对于SpringBoot,我使用的是JpaRepository,如果我打电话,我认为不会发生同样的事情:
jpaRepository.save(entity);
我认为通过此调用,具有指定 id 的 SubEntity 的其他字段将设置为 null!
对吗?
我有什么办法解决这个问题?
首先感谢您的回复!
你是对的,我不能这样做,也不能使用 EntityManager.merge() 方法!比我试图更好地解释我想要做什么:
假设我有一个复杂的实体,它有很多嵌套的实体(可能有嵌套的实体)如下:
@Entity
public class Car {
private String name;
....
....
private Engine engine; // nested entity
private Chassis chassis; // nested entity
}
还有:
@Entity
public class Engine {
private String company;
private Oil oil; // nested entity
....
}
现在假设在数据库中我有一辆汽车,所有关系都已填写(发动机、底盘、机油 ecc..),假设我想将汽车名称从法拉利更新为菲亚特,如果我使用纯 SQL,我可以简单地编写:
update Car c set c.name = "Fiat" where c.id = [id];
现在,如果我使用 Spring JPA,为了确保在我更新我的实体时所有嵌套实体(及其字段)都没有设置为 null,我必须这样做:
Car car = carRepository.findById([id]);
car.setName("Fiat"):
carRepository.save(car);
这样我将更新汽车名称,并且我确信所有其他实体都将保持设置,因为它们是由 findById() 方法加载的。
我的问题和我的目标是知道是否有办法做这样的事情:
Car car = new Car();
car.setId(1); // id of Ferrari car
car.setName("Fiat");
someRepositoryOrEntityManager.saveOrUpdate(car);
并通过 find 方法保留所有其他字段和关系而不加载所有这些(可能是由于性能原因)。
【问题讨论】:
标签: spring-boot jpa merge