У меня проблема с JPA в моем приложении. У меня есть родительский объект Artist с отношением one-to-one/many etch к другим объектам, которые я все настроил для ленивости. Я получаю эти сущности, используя запросы присоединения. Все это работает нормально, но иногда я получаю исключение LazyInitializationException. Я использую Stateless EJB с JPA в backend и Spring MVC на веб-уровне. Вот метод:Присоединение в JPA иногда вызывает LazyInitializationException
public Artist getArtistWithChildren(long id, boolean isFetchReviews, boolean isFetchRequests, boolean isFetchGigs, boolean isFetchVenues) {
StringBuilder sql = new StringBuilder();
sql.append("select a from Artist a join fetch a.members mrs");
if(isFetchReviews) {
sql.append(" left join a.reviews rvs");
} if(isFetchRequests) {
sql.append(" left join a.requests rqs");
} if(isFetchGigs) {
sql.append(" left join a.gigs gs");
} if(isFetchVenues) {
sql.append(" left join a.venues vs");
}
sql.append(" where a.id=:id");
TypedQuery<Artist> query = em.createQuery(sql.toString(), Artist.class);
query.setParameter("id", id);
query.setMaxResults(1);
List<Artist> resultList = query.getResultList();
return resultList.get(0);
}
А вот класс сущности Исполнитель
@Entity
@Table(name="ARTIST")
public class Artist extends DescribingEntity {
private static final long serialVersionUID = -7264327449601568983L;
@ManyToMany(mappedBy="artists", targetEntity=Member.class, fetch=FetchType.LAZY, cascade={MERGE, REFRESH})
private List<Member> members;
@OneToMany(mappedBy="artist", targetEntity=VenueReview.class, fetch=FetchType.LAZY, cascade={MERGE, REFRESH, REMOVE})
private List<VenueReview> reviews;
@OneToMany(mappedBy="artist", targetEntity=Gig.class, fetch=FetchType.LAZY, cascade={MERGE, REFRESH, REMOVE})
private List<Gig> gigs;
@OneToMany(mappedBy="artist", targetEntity=GigRequest.class, fetch=FetchType.LAZY, cascade={MERGE, REFRESH, REMOVE})
private List<GigRequest> requests;
@ManyToMany(cascade={MERGE, REFRESH}, fetch=FetchType.LAZY)
@JoinTable(name="VENUE_ARTIST_REL",
[email protected](name="ARTIST_ID", referencedColumnName="ARTIST_ID"),
[email protected](name="VENUE_ID", referencedColumnName="VENUE_ID"))
private List<Venue> venues;
getters and setters...
Я затем перейти в режим отладки, чтобы выяснить, что пошло не так, и как я пошаговый метод он не возвращает ошибки и никакое исключение не выбрасывается. Может быть, коллекция возвращается слишком рано, чтобы все данные из БД не успели правильно заполнить? Я новичок, когда речь заходит о JPA, поэтому, пожалуйста, дайте мне знать, что я сделал неправильно. Вот пример. Я использую левые соединения здесь, так как я НЕ ХОЧУ получить результаты, но мне нужна инстанцированная коллекция.
Я тестировал одно и то же, используя Arquillian, и никаких ошибок, у меня также есть аналогичные методы для других объектов, где сценарий один и тот же, просто его запуск вызывает ошибку, а пошаговая отладка - нет.
Использование Hibernate.initialize(Object o)
в детских коллекциях отлично работает, но, насколько мне известно, это нехорошо делать, так как я должен сделать запрос БД для каждого ребенка (исправьте меня, если я ошибаюсь).
Я добавил Pastebin ссылки трассировки стека
Я добавил трассировка стека как ссылка. – Johan
Без сеанса, не без транзакции. Например. удаленные объекты –
Мой плохой, да без сессии. Спасибо, что исправил меня. – Shriram