我正在尝试更新1:N关系中的N关系(原始解决方案)
class Person{
// id etc.
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval=true)
private List<Car> cars;
}
class Car{
// id etc.
@ManyToOne
private Person owner;
}
//吸引所有人并将其转化为地图
Map<id,Person> persons = personDAO.getALL().transformToMap();
// carprovider is entity from external db, it has all Car attributes and more.
List<CarProvider> cars = carDao.getAllFromProvider();
for( CarProvider car: cars ){
if( persons.contains(car.getOwner().getId()){
Person p = persons.get(car.getOwner().getId());
List<Car> c = p.getCars();
for( Car p_car: c ){
if( p_car.getId() == car.getId() ) // match
p_car.setDemage(car.getDemage());
}
}
}
personDAO.saveAll(persons.values())
基本上,我从新车的保险数据库中检索数据,我发现数据库中是否存在该车的所有者,如果是,请更新其车。
但是抛出:
org.springframework.dao.InvalidDataAccessApiUsageException:多个 同一实体的表示正在被合并
您可以看到我使用了LazyLoad,因此我也使用了:
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
我知道这是不好的做法,也是N + 1问题,但是,鉴于我每周只执行一次此任务,它仍然比使用EAGER一次加载所有关系要好。
我正在使用CrudRepository
为什么会这样? Havent之前曾遇到此错误,无法找到任何逻辑推理。同一实体的多个表示如何合并?
这仅在我使用LazyLoad时发生。此错误的发生必然与数据库中存在实体有关。例如
List<CarProvider> cars = carDao.getAllFromProvider();
还包含我已经保存在数据库中的汽车。因此,实体本身不会更新属性,但是saveAll()
将在与通过延迟加载获取的实体相同的实体上调用。
感谢帮助!