アプリケーションに User というエンティティがあるとします。各ユーザーは、レイジー フェッチを使用して読み込まれる多くの記事を持つことができます。
@Entity
@Table(name = "Users")
public class User {
private Integer id;
private Set<Article> articles = new HashSet<Article>();
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)
public Set<Article> getArticles() {...}
}
Web サービス側で、ID でユーザーをロードし、それを jersey Viewable JSP に渡して返して表示したいと考えています。また、リクエストごとに単一のセッションを使用したいと考えています。
@GET
public Response getUser() {
Session session = getSessionFactory().openSession();
session.beginTransaction();
User user = (User) session.getNamedQuery("getUserById").setInteger("id", 1).uniqueResult();
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("user", user);
Viewable v = new Viewable("/user", dataMap);
Response r = Response.ok(v).build();
session.getTransaction().commit();
session.close();
return r;
}
user.jsp で、記事にアクセスして印刷したいと考えています。
<c:forEach var="a" items="${it.user.articles}">
<span>${a.title}</span>
</c:forEach>
このコードを実行して JSP をリクエストしようとすると、例外がスローされます。
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: my.package.User.articles, no session or session was closed
これは、明らかに Viewable を作成し、それを ResponseBuilder に渡し、build() を呼び出しても、実際には JSP が作成されないために発生します。JSP は、メソッドが返されてセッションが閉じられた後、さらに下のどこかに作成されます。
明らかなオプションの 1 つは、記事のフェッチ タイプを熱心に設定することですが、ほとんどの場合、User オブジェクトを使用しているときに記事を読み込んだり表示したりする必要がないため、これは理想的ではありません。
メソッドが戻る前に jersey に jsp の解釈と構築を強制する方法はありますか? セッションを閉じるためにコードを渡すことができる onResponse または postResponse リスナーはありますか?
一般的に、休止状態セッションの開始/終了を処理する方法とは異なる方法で行うべきことはありますか? グーグルで調べてみると、リクエストごとに1つのセッションを使用することをほとんどの人が推奨しているように見えるので、それを試してみようと思いました.