StackruError при получении таблицы соединений ManyToMany с помощью Java EJB 3
У меня есть следующие сопоставления сущностей для моего приложения 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());
Это дает мне ошибку переполнения стека. Я верю, что нетерпеливая выборка может иметь к этому какое-то отношение, но в любом другом случае я хочу, чтобы изменения загружались при сканировании, и это вызовет много проблем в остальной части моего приложения, если я изменю тип выборки на ленивый.
Я переопределил 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% случаев (за 8 лет использования Hibernate это первый раз, когда я ' Я видел эту ошибку).
Один из способов исправить это - увеличить размер стека, но это увеличит размер всех потоков приложения (что может быть не очень хорошим). так, например, вы можете добавить опцию -Xss1m
когда вы запустите JVM, и вы получите размер стека 1 МБ. (размер стека по умолчанию варьируется от платформы к платформе, но я думаю, что обычно это 512 КБ)
Другой альтернативой является изменение сопоставления, но я думаю, что все они включают в себя небольшую денормализацию таблицы. Одним из вариантов является выравнивание дерева, поэтому при заданном сканировании вы можете получить все дочерние элементы сканирования одним запросом. В этом случае коллекция Crawl.changes содержит всех детей, внуков и т. Д. Сканирования.
*всегда есть способ