Hibernate 一对多双向关联:数据库和二级缓存的差异

Hibernate 一对多双向关联:数据库和二级缓存的差异,hibernate,ehcache,Hibernate,Ehcache,下面是两类的一部分 public class Address { Set<Employee>employees=new HashSet<Employee>(); public class Employee { private Address address;; 然后在新的会议上, employee= (Employee) session.get(Employee.class, 1l)l address=employee.getAddress(); em

下面是两类的一部分

public class Address {
    Set<Employee>employees=new HashSet<Employee>();

public class Employee {
    private Address address;;
然后在新的会议上,

employee= (Employee) session.get(Employee.class, 1l)l
address=employee.getAddress();
employee= (Employee) session.get(Employee.class, 2l);
address=employee.getAddress();
如果没有Ehcache,则address是Address12l的代理,因此员工所属集合的容器是Address12l。但使用Ehcache时,address是aproxy到Address34l的,因此我们特意设置了对地址的引用

我不知道这是怎么回事,因为

BackrefPropertyAccessor$BackrefSetter.set(Object, Object, SessionFactoryImplementor){
}

问题在于,您没有维护关系的双向性,而是依赖Hibernate和数据库的底层关系模型来为您修复关系。一旦使用有状态的OO表示,问题就会暴露出来。您很可能已经只在会话中观察到了它

基本上,您只更新关系的拥有方,而不是两者。如果基础数据库是关系数据库,并且仅在一端保存FK,那么从该模型重新加载时,问题就消失了


您需要做的是更新关系的两端,即employee.setAddress和address.addEmployee,而不是向用户公开原始集。此外,如果该员工已经关联到另一个地址,则也需要将其从该地址集中删除。。。这就是OO非常方便的地方:由于此逻辑实际上应该是模型上.setAddress或.addEmployee方法的一部分,它将检查是否有任何东西需要清理,并回调到另一端,将该逻辑巧妙地封装在远离Address或Employee类的使用者的地方。

当我不使用二级缓存时,它可以工作。问题是当存在二级缓存时。是的,缓存实际上使用的是比RDBMS更多的OO模型,但OO代码才是问题所在,只有以这种方式使用模型,您才能发现问题。看见
employee= (Employee) session.get(Employee.class, 1l)l
address=employee.getAddress();
employee= (Employee) session.get(Employee.class, 2l);
address=employee.getAddress();
BackrefPropertyAccessor$BackrefSetter.set(Object, Object, SessionFactoryImplementor){
}