我目前正在将一个(工作中的)应用从使用EclipseLink迁移到Hibernate JPA,大部分情况下都很顺利,但我发现有一件事情无法解释,也想不到任何好的搜索词!
基本上,我有四个实体,它们之间形成了一个一对多关系链:
EntityA有一个EntityB列表,每个EntityB又有一个EntityC列表,每个EntityC又有一个EntityD列表
每个实体都有一个相反方向的多对一关系,因此:
EntityD有一个EntityC,EntityC有一个EntityB,EntityB有一个EntityA。
这是(为了清晰起见大大简化了):
@Entity
public class EntityA {
@OneToMany (cascade = CascadeType.All, mappedBy = "entityA")
private List<EntityB> entityBList;
...
}
@Entity
public class EntityB {
@OneToMany (cascade = CascadeType.All, mappedBy = "entityB")
private List<EntityC> entityCList;
@JoinColumn (name = "ENTITY_A", referencedColumnName = "ENTITY_A_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityA entityA;
}
@Entity
public class EntityC {
@OneToMany (cascade = CascadeType.ALL, mappedBy = "entityC")
private List<EntityD> entityDList;
@JoinColumn (name = "ENTITY_B", referencedColumnName = "ENTITY_B_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityB entityB;
}
@Entity
public class EntityD {
@JoinColumn (name = "ENTITY_C", referencedColumnName = "ENTITY_C_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityC entityC;
}
我从数据库中获取一个EntityA(通过它的主键查找),因此获得了一个已经填充好的EntityA实例,其中包含一个PersistentBag用于我的List<EntityB>。当我解引用该List<EntityB>时,我看到了一个延迟加载的情况,同样地,当我从EntityB中获取EntityC时也是如此。
此时,一切都符合我的预期,我有一个EntityA、B和C,它们都完全填充了来自数据库的值,但是当我尝试从EntityC获取我的EntityD时,发现它是null。
在这一点上,我的实体管理器仍然是打开且活动状态的,即使我在获取EntityA后立即在调试器中查看它,我也可以遍历关系,直到EntityC,并再次看到'entityDList'为null。
到目前为止,我找到的唯一解决方法是使用:
EntityManager.refresh(entityC);
这段代码会填充所有元素,包括懒加载的PersistentBag实体DList。
因此,我的猜测是Hibernate只填充2级(或3级,取决于如何计算)的引用,然后放弃,尽管我不真正理解为什么会这样。有人能理解吗?
除了使用.refresh之外,是否有其他解决方案?有没有一种配置或注释值,可以让Hibernate完全填充引用对象?