我的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生成的,我选择了要在其中使用的主键,其他类都使用相同的东西。
答案 0 :(得分:0)
如果对象树的整个树很大,那么没有办法 *来避免堆栈溢出,因为hibernate递归地解析了依赖关系,这对于99.9%的情况是可以的(在8年的使用中) hibernate,这是我第一次看到这个错误。)
解决此问题的另一种方法是增加堆栈大小,但这会增加所有应用程序线程的大小(这可能不是很好)。例如,您可以在运行JVM时添加选项-Xss1m
,并获得1mb的堆栈大小。 (默认堆栈大小因平台而异,但我认为通常为512k)
另一个替代方案是更改映射,但我认为所有都包括对表进行非规范化。 一种选择是展平树,因此给定特定的爬网,您可以使用一个查询检索爬网的所有子项。在这种情况下,集合Crawl.changes包含爬网的所有子项,孙子等。
* 始终有一种方式