#java #hibernate #jpa #jakarta-ee #ejb
#java #переход в спящий режим #jpa #джакарта-ee #ejb
Вопрос:
У меня есть следующие сопоставления объектов для моего приложения 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 resu<
}
@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. Я бы рекомендовал теги jpa или hibernate вместо некоторых других (например, stackoverflowerror или ejb).
2. @bkail не могли бы вы объяснить, почему? Я использую аннотации EJB3 (JPA) без каких-либо проблем в течение 4 лет.
3. @Augusto Я имею в виду stackoverflow.com теги вопросов; Эксперты JPA или hibernate могут пропустить вопрос с текущим набором тегов.
4. Хорошо, спасибо, я их изменил.
Ответ №1:
Если все дерево дерева объектов большое, нет способа * избежать stackoverflow, поскольку hibernate рекурсивно разрешает зависимости, что нормально для 99,9% случаев (за 8 лет использования hibernate я впервые вижу эту ошибку).
Одной из альтернатив для исправления этого является увеличение размера стека, но это увеличит размер во всех потоках приложения (что может быть не очень хорошо). так, например, вы можете добавить опцию -Xss1m
при запуске JVM, и вы получите размер стека в 1 мб. (размер стека по умолчанию варьируется от платформы к платформе, но я думаю, что обычно это 512 кб)
Другой альтернативой является изменение сопоставления, но я думаю, что все они включают небольшую денормализацию таблицы. Один из вариантов — сгладить дерево, чтобы при определенном обходе вы могли получить все дочерние элементы обхода одним запросом. В этом случае обход коллекции.changes содержит все дочерние элементы, внуков и т.д. обхода.
* всегда есть способ
Комментарии:
1. Спасибо за ответ, я не думаю, что это проблема с размером базы данных, в настоящее время я тестирую ее с помощью 1 обхода и 6 страниц и 6 изменений. Что именно вы подразумеваете под искажением дерева? Будет ли это включать комбинацию таблицы изменений и страницы?
2. Ибп, это другое. Можете ли вы подтвердить, что у вас нет циклической связи? Например, pageX включает changeX; changeX имеет CrawlX, а CrawlX включает changeX.
3. Я полагаю, что это так. В нынешнем виде выполняется только один обход, поэтому все изменения будут сохранять этот обход, а обход будет сохранять все изменения. Я думал, что hibernate обнаружит циклическую связь и не застрянет в цикле. Есть ли способ обойти это? Я неправильно отображаю отношения «многие ко многим»? Возможно, я пропускаю некоторые аннотации?
4. Я не думаю, что это работает для отношений «один ко многим», но это работает для отношений «многие ко многим». Это не идеально, если вы извлекаете связь с другой таблицей, вы могли бы обмануть hibernate и отобразить связь как «многие ко многим». О, и не могли бы вы опубликовать хэш-код и equals? Потому что это может произойти, если они неверны.
5. Я отредактировал исходное сообщение с помощью методов hashcode и equals. Что именно будет включать в себя извлечение связей?