3

私は次のJSF/PrimeFacesEJBアーキテクチャを持っています:

[JSF /PrimeFacesxhtmlビュー]->[@ManagedBeanJSF Bean]-> [@Stateless EJB3 Bean] --JPA-> [DB]

つまり、JSFビューは、バッキングBean(@ManagedBean)でアクセスするエンティティとコレクションを表示します。これらのコレクションとエンティティは、 EntityManagerが注入されたステートレスEJB3「ファサード」Beanを呼び出してフェッチされ、 JPAを使用してデータベースにアクセスします。休止状態。ステートレスEJB3Beanもいくつかのサービスを提供しますが、それらの役割の大部分は、それらを表示する必要があるxhtmlビューによって要求されるように、データベースからエンティティオブジェクト( JPA注釈付き)を提供することです。

これが重要です。私の理解が正しければ、エンティティBeanがステートレスEJB3 Beanによって返されるとすぐに、各EJB3Beanメソッドがトランザクションを区切るときにエンティティBeanが切り離されます。その場合、xhtmlビューとJSFマネージドBeanがフェッチされたエンティティオブジェクト(1対多のコレクションなど)のグラフをナビゲートするときに、次のようなレイジー初期化例外が発生することがよくあります。

javax.el.ELException: ... org.hibernate.LazyInitializationException: failed
to lazily initialize a collection of role: ..., no session or session was closed

動作する唯一のことは、コレクションをEAGERでロードするように変更することですが、これは実用的な解決策ではありません。デタッチされたJPAエンティティがビューレイヤーへの道を見つけるときに使用するいくつかの良いパターンは、各ケースをアドホックな方法で処理するのではなく、すべての遅延初期化例外を回避するために何ですか?

4

1 に答える 1

4

遅延関連付けを処理する方法は 2 つあります。最初の方法は、以下を使用してエンティティを初期化することです。

Hibernate.initialize(proxy)

または、読み込み時にエンティティ全体を取得するフェッチ タイプを EAGER に設定します。2 番目のより適切な方法 (私の意見では) は、エンティティを保持している限り、エンティティ マネージャーを保持することです。これは、次のような @Stateful セッションを使用して行うことができます。

@Stateful
public class UserService {
   @PersistenceContext(type=EXTENDED)
   private EntityManager entityManager;

   ...... the business method
}

エンティティを保持している限り、ejb への参照を保持します。拡張永続コンテキストの詳細については、こちらを参照してください。エンティティ マネージャを保持する他の方法は、 Seam -persistenceCODIなどの CDI モジュールを使用して、EntityManager を作成し、会話スコープに保持する機能を提供することです。

于 2012-10-26T17:37:07.237 に答える