使用Java EJB 3检索多个联接表时休眠StackOverflower错误
我的EJB3应用程序有以下映射多对多关系的实体映射:
@Entity
Crawl{
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.crawl")
public List<Change> changes;
}
@Entity
Change{
@EmbeddedId
ChangePK pk;
@Temporal(javax.persistence.TemporalType.DATE)
Date changeDate;
}
@Embeddable
ChangePK{
@ManyToOne
Crawl crawl;
@ManyToOne
Page page;
}
@Entity
Page{
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.page")
List<Change> changes;
}
我正在尝试获取与爬网相关的所有更改,并使用以下命令按日期排序:
this.entityManager
.createQuery("SELECT c FROM Change c WHERE
c.pk.crawl.id = :id
ORDER BY c.changeDate DESC")
.setParameter("id", crawl.getId());
这给了我一个堆栈溢出错误。我相信急切的获取可能与此有关,但在其他任何情况下,我都希望用爬网加载更改,如果我将获取类型更改为lazy,将在应用程序的其余部分造成很多问题
我为每个类重写了hashCode
和equals
方法
编辑:
hashcode
和equals
代码:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Crawl other = (Crawl) obj;
if (id != other.id)
return false;
return true;
}
这些都是由Eclipse生成的,我已经选择了要在其中使用的主键,其他类都使用相同的东西
# 1 楼答案
如果对象树的整个树都很大,那么当hibernate递归地解决依赖关系时,就没有办法避免堆栈溢出,这在99.9%的情况下是可以的(在使用hibernate的8年中,这是我第一次看到这个错误)
解决这个问题的另一种方法是增加堆栈大小,但这会增加所有应用程序线程的大小(这可能不是什么好事)。例如,当运行JVM时,可以添加选项
-Xss1m
,得到1mb的堆栈大小。(默认堆栈大小因平台而异,但我认为通常是512k)另一种选择是更改映射,但我认为所有这些都包括对表进行一点非规范化。 一个选项是展平树,因此给定一个特定的爬网,您可以通过一个查询检索爬网的所有子级。在本例中,集合爬网。“更改”包含爬网的所有孩子、孙子等
*总有办法