私のアプリケーションでJPAにこの問題があります。私はすべてが怠惰にフェッチされるように設定されている他のエンティティと1対1 /多くのエッチ関係を持つ親エンティティアーティストを持っています。私は結合クエリを使用してこれらのエンティティを取得します。これはすべて正常に動作するようですが、時々私はLazyInitializationExceptionを取得します。私はステートレスEJBをバックエンドにJPA、Web層に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...
である私はそれがエラーを返していない方法をステップ実行していて、私はその後、何が悪かったのかを調べるためにデバッグモードに入ると、例外はスローされません。コレクションがあまりに早く返され、DBからのすべてのデータが正しく設定される時間がないことがありますか? JPAについては初心者ですので、間違ったことを教えてください。ここに例があります。結果を取得する必要はありませんので、ここでは左結合を使用していますが、インスタンス化されたコレクションが必要です。
Arquillianを使用して同じことをテストしましたが、エラーはありません。シナリオが同じ他のエンティティに対しても同様の方法があります。単に実行すると、ステップスルーデバッグ中にエラーが発生します。
子コレクションでHibernate.initialize(Object o)
を使用するとうまくいきますが、私が間違っている場合は正しい子供になるようにDBのクエリを作成する必要があるため、私の知る限りそれはできません。
私はあなたのコレクションの遅延ロードだと囲むセッションを持ってして、そのコレクションにアクセスしようとすると、LazyInitializationExceptionが発生し、スタックトレース一般に
私が追加スタックトレースをリンクとして使用します。 – Johan
セッションなしではなく、トランザクションなし。例えば。デタッチされたエンティティ –
私の悪い、セッションなしのはい。私を修正してくれてありがとう。 – Shriram