0

VaadinとJPAPersistenceレイヤーを使用して、簡単な概念実証を行おうとしています。

私は、fetchType = Lazyの@OneToMany関係を持つBeanを持っており、このBeanのコレクションをDAOを使用してテーブルに追加しようとしています。次の例外があります:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: common.domain.Bill.detail, no session or session was closed

JPAContainerなしでVaadinとJPAを操作する方法はありますか?

ありがとう。

4

3 に答える 3

0

lazyquerycontainerアドオンの EntityContainer クラスを使用しています。名前が示すように、遅延読み込みをサポートします。それはちょうど動作します:)

サンプルコード:

    resultsTable = new Table();

    resultsTable.setSelectable(true);
    resultsTable.setCaption("JpaQuery");
    resultsTable.setPageLength(40);
    resultsTable.setImmediate(true);
    resultsTable.setEditable(false);
    resultsTable.setWriteThrough(true);

    container = new EntityContainer<Call>(em, false, true, true, Call.class, 100, new Object[] {"imsi"}, new boolean[] {true});

    container.addContainerProperty(LazyQueryView.PROPERTY_ID_ITEM_STATUS, QueryItemStatus.class, QueryItemStatus.None, true, false);
    container.addContainerProperty("startTime", Date.class, null, true, true);
    container.addContainerProperty("stopTime", Date.class, null, true, true);
    container.addContainerProperty("imsi", String.class, null, false, true);
    container.addContainerProperty("imei", String.class, null, false, true);
    container.addContainerProperty("callType", Integer.class, null, true, true);
    container.addContainerProperty("cdpn", String.class, null, true, true);
    container.addContainerProperty("cgpn", String.class, null, true, true);
    container.addContainerProperty("status", Integer.class, null, true, true);
    container.addContainerProperty("mmRelCause", Integer.class, null, true, true);
    container.addContainerProperty("rrRelCause", Integer.class, null, true, true);

    resultsTable.setContainerDataSource(container);

    resultsTable.setVisibleColumns(new String[] {"startTime" , "stopTime" , "imsi", "imei", "callType" , "cdpn", "cgpn", "status", "mmRelCause"      , "rrRelCause" });
    resultsTable.setColumnHeaders(new String[]  {"Start time", "Stop time", "IMSI", "IMEI", "Call Type", "CDPN", "CGPN", "Status", "MM Release Cause", "RR Release Cause"});

    resultsTable.setColumnCollapsingAllowed(true);
    resultsTable.setColumnCollapsed("mmRelCause", true);
    resultsTable.setColumnCollapsed("rrRelCause", true);

JQLに基づいてデータをフィルタリングするには、filterフィルター文字列とバインド変数のマップを渡すメソッドを実行できます。

...
whereParameters.put("stopTimeFrom", filterParams.getStopTimeFrom());                    
where = "e.startTime >= :stopTimeFrom";
...

container.filter(where, whereParameters);

Criteria API を使用する場合は、criteriacontainerを使用できます。

于 2012-07-13T16:33:19.827 に答える
0

Bean(Item)Container を使用して、そこにエンティティを追加できます。

コンテナを使用するだけであれば、JPAContainer の場合のように遅延読み込みを行う必要はありません。

コンテナーを使用するコンポーネントはコンテナーからの遅延読み込みを行いますが、すべてのオブジェクトはコンテナー内に保持されます。コンテナの遅延読み込みは自分で行う必要があります。

Bean(Item)Container およびコンテナ全般の詳細については、こちらを参照してください。

于 2012-07-07T21:07:45.183 に答える
0

これは古い投稿ですが...

ユースケースを見てみましょう:
- ブラウザがアプリケーションをリクエストします
- サーバー側のコードでは、EntityManager を使用して Bean をロードします (Bean はセッションにあります) が、その関係インスタンス (遅延) はプロキシです => 関係インスタンスは、最初にアクセスしたときにのみロードされます
- ブラウザが応答を受け取ります -
サーバーにリクエストを送信するボタン(たとえば)をクリックします
- 遅延関係に何かを追加/変更しようとします
-プロキシにセッションがありません (以前のセッションで作成されましたが、現在はセッションにもアタッチされていません)、例外をスローします

次の解決策のいずれかを試すことができます:
1- Bean のマージを試みます (Bean を現在のセッションにアタッチします):bean = em.merge(bean);遅延関係を追加/変更する直前
2- エンティティをロードするときに遅延関係のロードを強制してみてください初めて: bean.getMyLazyRelationship();
3- エンティティを変更する前に再度ロードします
4- LAZY を EAGER に変更しますが、(多くの場合) 適切な解決策ではありません

コンテナーを使用すると、この問題が解決する場合としない場合があります

それが役に立てば幸い

于 2013-03-18T13:21:22.970 に答える