【问题标题】:hibernate @ManyToMany bidirectional eager fetchinghibernate @ManyToMany 双向渴望获取
【发布时间】:2011-04-28 01:59:06
【问题描述】:

我有一个我认为应该很常见的问题,但我找不到答案。

我有 2 个对象:组和用户。我的课程看起来像这样:

class Group
{
  @ManyToMany(fetch = FetchType.EAGER)
  List<User> users;
}

class User
{
  @ManyToMany(fetch = FetchType.EAGER)
  List<Group> groups;
}

现在,当我尝试从数据库中获取用户时,它会带来其所有组,所有组都会带来其所有用户,依此类推。最后,我得到了一个 stackoverflow 异常。

我怎样才能解决这个问题,并且仍然有我的双向关联和访问列表中的对象的能力?

【问题讨论】:

    标签: hibernate many-to-many fetch


    【解决方案1】:

    如果您使用mappedBy 属性(无论如何都应该使用该属性)将双向关联的一侧设为关联的拥有 一侧,您会遇到同样的问题吗?像这样:

    @Entity public class Group {
      ...
      @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups")
      List<User> users;
    }
    
    @Entity public class User {
      ...
      @ManyToMany(fetch = FetchType.EAGER)
      List<Group> groups;
    }
    

    更新:我找不到任何证据表明禁止在双向关联的两侧使用 EAGER 获取,并且 AFAIK,在 Hibernate 文档中没有提到这样的限制,并且/ 或 JPA 规范。

    实际上,根据 Emmanuel Bernard 的 this comment 到一个(有点相似的)问题:

    LAZYEAGER 应该与代码库中的无限循环问题正交。 Hibernate 知道如何处理循环图

    对我来说,上面的内容很清楚,Hibernate 应该能够处理您的映射(正如我在评论中提到的),我很想将任何矛盾的行为视为错误。

    如果您可以提供一个允许重现问题的测试用例,我的建议是打开一个问题。

    【讨论】:

    • 是的。同样的事情也会发生。我可以理解,b/c hibernate 需要为每个列表带来所有列表对象,这是一个无限循环。我的问题是是否有可能限制休眠带来对象的深度(类似于 fetch_max_depth 但用于多对多)。
    • @Rafa 实际上,我希望 Hibernate 能够检测到循环并执行适当的操作(但我没有花时间对此进行测试)。另一方面,我不能说这种急切地加载多对多的双方看起来是个好主意。
    【解决方案2】:

    当 Hibernate 尝试急切地获取所需的所有内容时,它可以正常工作。建模对象必须考虑休眠,因此不会发生循环和 stackoverflow 异常。

    我所做的是删除关系的一侧。您可以决定是要删除该侧还是保留它并将另一侧定义为所有者。您还需要从那一侧移除急切获取。

    如果 hibernate 可以提供一种机制来定义多对多关系中的获取深度,那就太好了。

    【讨论】:

      【解决方案3】:

      您可能希望将属性“hibernate.max_fetch_depth”设置为 3 之类的值以限制急切获取。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-15
        • 2012-04-30
        • 2014-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多