Java 带有Hibernate 3的JPA-多个堆栈溢出和多个包错误
在检索具有双向多对多关系的实体的数据时,我遇到了一些问题。如果我使用Java 带有Hibernate 3的JPA-多个堆栈溢出和多个包错误,java,hibernate,orm,jpa-2.0,Java,Hibernate,Orm,Jpa 2.0,在检索具有双向多对多关系的实体的数据时,我遇到了一些问题。如果我使用List存储实体,我将无法同时提取多个行李。如果我将代码更改为使用Set,则会出现stackoverflow错误 详情: Spring 3.0.3 Hibernate核心:3.5.1-Final Hibernate注释:3.5.1-Final hibernate通用注释:3.2.0-Final hibernate entitymanager:3.5.1-Final Mysql数据库 少年4 用户拥有多个银行账户;银行账户可以
List
存储实体,我将无法同时提取多个行李。如果我将代码更改为使用Set
,则会出现stackoverflow错误
详情:
- Spring 3.0.3
- Hibernate核心:3.5.1-Final
- Hibernate注释:3.5.1-Final
- hibernate通用注释:3.2.0-Final
- hibernate entitymanager:3.5.1-Final
- Mysql数据库
- 少年4
@ManyToMany(fetch = FetchType.EAGER, mappedBy="user")
private List<BankAccount> bankAccounts = new ArrayList<BankAccount>();
问题
getAllUsers
)时,我无法同时获取多个包Set
和HashSet
而不是List和ArrayList
,我会得到stackoverflow错误请帮助我,让我知道代码是否错误,或者我正在使用的特定版本的libs是否存在已知的hibernate问题。您无法在两个列表上映射多对多关系,然后hibernate将尝试为每个嵌套元素获取一个集合,即用户列表中的每个用户都有一个银行帐户列表,其中有一个用户列表。把它想象成一个永无止境的递归 (现在让我们把
fetch
属性放在一边)。您的映射是完全有效的,并且是映射双向多对多关系的正确方法。来自JPA 2.0规范:
2.10.4双向多关系
示例:
@Entity
public class Project {
private Collection<Employee> employees;
@ManyToMany
public Collection<Employee> getEmployees() {
return employees;
}
public void setEmployees(Collection<Employee> employees) {
this.employees = employees;
}
...
}
@Entity
public class Employee {
private Collection<Project> projects;
@ManyToMany(mappedBy="employees")
public Collection<Project> getProjects() {
return projects;
}
public void setProjects(Collection<Project> projects) {
this.projects = projects;
}
...
}
@实体
公共类项目{
私人收藏员工;
@许多
公共集合getEmployees(){
返回员工;
}
公共雇员(收款雇员){
这是。雇员=雇员;
}
...
}
@实体
公营雇员{
私人收藏项目;
@许多人(mappedBy=“员工”)
公共收集项目(){
返回项目;
}
公共项目(收集项目){
这个项目=项目;
}
...
}
在本例中:
- 实体
引用实体项目
的集合员工
- 实体
引用实体Employee
项目的集合
- 实体
是关系的所有者Project
earge
抓取时的行为(这会导致无限循环吗?),JPA规范对此非常模糊,我找不到任何明确的提及它是被禁止的。但我敢打赌这是问题的一部分
但在Hibernate的特殊情况下,我希望Hibernate能够处理Emmanuel Bernard中提到的周期:
懒惰或渴望应该与代码库中的无限循环问题正交。Hibernate知道如何处理循环图
有趣的是,我最近已经回答了(非常接近的问题)可能暗示Hibernate中出现了问题(我对上述评论的理解是,在两侧都使用急切抓取应该是可行的)
因此,我将以同样的方式总结我的答案:如果您可以提供一个允许重现问题的测试用例,打开一个Jira问题。我遇到过类似的问题,根本原因是上面提到的Lombok生成代码。我的代码使用注释@Data,它生成具有交叉依赖字段的hashCode和ToString方法,这种结构导致Hibernate停滞。因此,应该注意避免这些无限循环调用,在我的例子中,我刚刚添加了排除参数,如@EqualsAndHashCode(exclude=“dependent\u list”)和@ToString(exclude=“dependent\u list”)。它解决了堆栈溢出问题。我也面临同样的问题 问题在于lombok库中的@Data注释
为了修复它,我用@Getter、@Setter替换了@Data。并在类上定义了一个自定义的toString()方法。您好,非常感谢您的回复。但是,由于这是一种多对多关系,我们不需要两边都有集合吗?为了让hibernate映射集合,只需要一侧。在hibernate注释文档中:“如前所述,另一方不必(不得)描述物理映射:一个简单的mappedBy参数包含所有者方属性名,将两者绑定。”我通过从toString()方法中删除其他实体的引用,解决了这个问题。i、 e从用户对象的toString方法中删除BankAccount的引用,反之亦然。我还从所有实体中删除了fetch=fetchType.EAGER,我认为hibernate能够检测到这样一个循环依赖项,而不会抛出stackoverflow异常。我为这个问题添加了JIRA以及完整的源代码。我在两个实体之间的多对多关系上使用Lombok的ToString注释时遇到了一个非常类似的问题。解决方案:使用ToString注释的exclude属性。无论如何,Hibernate可以很好地处理多对多关系,在这种关系中双方都被急切地抓取。另一种方法是使用
@ToString.Exclude
和@EqualsAndHashCode.Exclude
@arnonuem注释字段。是的,但是如果Lombok版本是1.16.22或更高
Users
user_id PK
Bankaccount
bank_account_id PK
user_bankaccount
bank_account_id PK ( references bankaccount.bank_account_id )
user_id PK ( references user.user_id )
@Entity
public class Project {
private Collection<Employee> employees;
@ManyToMany
public Collection<Employee> getEmployees() {
return employees;
}
public void setEmployees(Collection<Employee> employees) {
this.employees = employees;
}
...
}
@Entity
public class Employee {
private Collection<Project> projects;
@ManyToMany(mappedBy="employees")
public Collection<Project> getProjects() {
return projects;
}
public void setProjects(Collection<Project> projects) {
this.projects = projects;
}
...
}