代码之家  ›  专栏  ›  技术社区  ›  DaveyDaveDave max

Hibernate JPA-未填充多通关系

  •  6
  • DaveyDaveDave max  · 技术社区  · 14 年前

    我目前正在移动一个(工作)应用程序从使用EclipseLink到HibernateJPA,大多数情况下它进展得相当顺利,但我发现一件事我无法解释,也无法想出任何好的搜索词!

    EntityA有一个EntityB的列表,每个EntityB都有一个EntityC的列表,每个EntityD都有一个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;
    }
    

    List<EntityB> . 我看到一个懒负载发生时,我取消引用 列表<实体b>

    在这一点上,一切都如我所期望的那样,我有一个EntityA,B和C,所有这些都被数据库中的值填充,但是我试图从EntityC中获取我的EntityD,发现它是空的。

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

    EntityManager.refresh(entityC);
    

    它填充其所有元素,包括entityDList的延迟加载的PersistentBag。

    所以,我猜Hibernate只填充了2层深度的引用(或者3层,这取决于你怎么计算),然后就放弃了,尽管我真的不明白为什么会这样。有人这么认为吗?

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

    3 回复  |  直到 14 年前
        1
  •  3
  •   DaveyDaveDave max    6 年前

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

    max_fetch_depth 建议,但出于某种原因,它不适合我(我想知道为什么?)。

    同样,如果你的 @OneToMany s是集合,而不是列表,按照Albert的建议,执行一个急取或左连接可能会起作用,但是显然Hibernate只允许您最多有一个急取的列表,如果您需要更多,那么您的集合应该是集合。我没有试过,但我怀疑它可能解决了问题。

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

        2
  •  1
  •   Albert    14 年前

    这真有趣。解决这一问题的一种方法是查询左联接对象获取到->B->C->如果你要向下移动到物体,速度也会更快。 应该是这样的。

    "from A left join fetch B left join fetch C left join fetch D"
    

    您是否也尝试过从C建立关系->你渴望什么?好奇接下来会发生什么。。。

        3
  •  1
  •   ambassador86    14 年前