2010-10-20 73 views
7

我有一个问题,我认为应该很常见,但我找不到答案。hibernate @ManyToMany双向渴望提取

我有2个对象:组和用户。我的课是这个样子:

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

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

现在,当我尝试从数据库中获取用户它把它的所有组和所有组将其所有的用户等。最后,我得到了一个stackoverflow例外。

我该如何解决这个问题,仍然有我的双向关联和到达列表中的对象的能力?

回答

8

如果您使用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取上一个双向关联两侧,严禁转载,据我所知,有Hibernate文档中没有这样的限制,并提及/或JPA规范。

实际上,根据this comment从灵光伯纳德一个(在某种程度上类似的)问题:

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

对于我来说,上面是很清楚的,休眠应该能够处理你的映射(正如我在评论中提到),我会受到诱惑而考虑任何矛盾的行为作为错误。

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

+0

是的。同样的事情发生。我可以理解,这是有道理的b/c休眠需要为每个列表带来所有列表对象,并且它是一个无限循环。我的问题是,如果有可能限制休眠带来的对象的深度(类似fetch_max_depth,但对于多对多)。 – refaelos 2010-10-21 12:49:16

+0

@Rafa实际上,我希望Hibernate能够检测周期并做适当的事情(但我没有花时间来测试它)。另一方面,我不能说这种急切的加载多对多看起来是个好主意。 – 2010-10-21 13:02:49

0

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

我做的是删除关系的一方。您可以决定是否要删除该边或将其保留并将另一边定义为所有者。您还需要从该端删除渴望的提取。

如果hibernate能够提供一种机制来定义多对多关系中的抓取深度,那将会很不错。

0

您可能希望将属性“hibernate.max_fetch_depth”设置为3,以限制提前获取。