Hibernate JPA - 没有填充ManyToOne关系

Dav*_*ave 6 java orm hibernate jpa lazy-loading

我目前正在将一个(工作)应用程序从使用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;
}
Run Code Online (Sandbox Code Playgroud)

我从数据库中获取了一个EntityA(通过它的主键查找),从而得到一个填充良好的EntityA实例,我的PersistentBag List<EntityB>.当我取消引用时,我看到发生了一个延迟加载List<EntityB>,并且从EntityB获取EntityC也是如此.

在这一点上,一切都如我所料,我有一个EntityA,B和C都完全填充了数据库中的值,但后来我尝试从EntityC获取我的EntityD,并发现它是null.

我的实体管理器此时仍处于打开和活动状态,即使我在获得EntityA后立即在调试器中查看它,我也可以遍历关系,直到EntityC,并再次将'entityDList'视为null.

到目前为止我找到的唯一解决方案是使用:

EntityManager.refresh(entityC);
Run Code Online (Sandbox Code Playgroud)

它填充所有元素,包括一个延迟加载的实体DLL的PersistentBag.

所以,我的猜测是Hibernate只填充2级深度的参考(或3,取决于你的计算方式),然后放弃,尽管我不明白为什么会这样.这对任何人都有意义吗?

除了.refresh之外还有其他解决方案吗?某种配置或注释值会使Hibernate一直填充引用?

Dav*_*ave 3

感谢这里的人的建议,这些建议可能是相关的,但对我的具体情况没有帮助。

如果您正在阅读本文并遇到同样的问题,那么可能值得尝试该max_fetch_depth建议,但由于某种原因它对我不起作用(我希望得到关于为什么的建议?)。

同样,如果你的@OneToManys是集合,而不是列表,按照Albert的建议进行急切获取或左连接可能会起作用,但显然Hibernate只允许你最多有1个急切获取的列表,如果你需要超过也就是说,你的收藏应该是 Sets。我没有尝试过,但我怀疑它可能已经解决了问题。

除非有人有更好的建议,否则我将坚持调用刷新,这实际上可能对我的应用程序更有意义。