我正在重写一个大项目SpringBoot 2.2.6
我遇到了问题。
在旧项目中(纯ejb
)当更新复杂实体时,代码构建entity
from DTO's
如下:
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
}
And:
@Entity
public class Engine {
private String company;
private Oil oil; // nested entity
....
}
现在假设在数据库中我有一辆汽车,填充了所有关系(发动机、底盘、油等..),并且假设我想将汽车名称从 Ferrari 更新为 Fiat,如果我使用纯 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 方法加载所有这些字段和关系(可能是由于性能原因)。