Hibernate JPA - 没有填充ManyToOne关系
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate JPA - 没有填充ManyToOne关系相关的知识,希望对你有一定的参考价值。
我目前正在将一个(工作)应用程序从使用EclipseLink转移到Hibernate JPA,大多数情况下它已经非常顺利,但我发现了一件我无法解释的事情,也无法想到任何好的搜索术语!
基本上,我有四个实体,一对多的关系形成一个链:
EntityA有一个EntityB列表,每个列表都有一个EntityC列表,每个列表都包含一个EntityD列表
然后,每个人都有一个多对一的关系,所以:
EntityD有一个EntityC,它有一个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实例,我的List<EntityB>
使用PersistentBag。当我取消引用List<EntityB>
时,我发现了一个懒惰的负载,并且从EntityB获取EntityC也是如此。
在这一点上,一切都如我所料,我有一个EntityA,B和C都完全填充了数据库中的值,但后来我尝试从EntityC获取我的EntityD,并发现它是null。
我的实体管理器此时仍处于打开和活动状态,即使我在获得EntityA后立即在调试器中查看它,我也可以遍历关系,直到EntityC,并再次将'entityDList'视为null。
到目前为止我找到的唯一解决方案是使用:
EntityManager.refresh(entityC);
它填充所有元素,包括一个延迟加载的实体DLL的PersistentBag。
所以,我的猜测是Hibernate只填充2级深度的参考(或3,取决于你的计算方式),然后放弃,尽管我不明白为什么会这样。这对任何人都有意义吗?
除了.refresh之外还有其他解决方案吗?某种配置或注释值会使Hibernate一直填充引用?
感谢这里的人们的建议,这可能是相关的,但对我的具体案例没有帮助。
如果你正在阅读这个遇到同样的问题,它可能值得尝试max_fetch_depth
的建议,但由于某种原因它不适合我(我喜欢建议为什么?)。
同样地,如果你的@OneToMany
s是集合,而不是列表,做一个急切的提取或左连接,正如阿尔伯特所建议的那样可能有效,但显然Hibernate只允许你最多获得1个急切获取的List,如果你需要更多那个,你的收藏品应该是套装。我没有尝试过,但我怀疑它可能已经解决了这个问题。
除非有人有更好的建议,否则我会坚持使用调用刷新,这实际上可能对我的应用程序更有意义。
这确实很有趣。解决它的一种方法是查询对象A左连接 - 获取 - > B-> C-> D,如果你要遍历到对象D,也会更快。这将是这样的。
"from A left join fetch B left join fetch C left join fetch D"
你是否也试过从C-> D渴望建立关系?好奇会发生什么......
hibernate文档说你可以用hibernate.max_fetch_depth属性设置它。默认值为3.您可以在第47页的"Hibernate Reference Documentation"中找到它。
以上是关于Hibernate JPA - 没有填充ManyToOne关系的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Hibernate 和 JPA 处理填充下拉列表?
Hibernate CriteriaQuery where - ManyToOne 字段
Spring Boot 和 Hibernate Envers:手动更新 AUD-Table