26

Hibernate Enversでは、設定されているフェッチタイプに関係なく、エンティティの関連するすべてのコレクションが遅延ロードされます。したがって、他のエンティティのコレクション(もちろん両方とも監査済み)を持つエンティティを監査クエリする場合、コレクションはSetProxy最初は(デバッグ時に表示されます)です。

では、どうすればそのプロキシを初期化できますか?使用しHibernate.initialize()ても効果はありません(HibernateとEnversが異なるプロキシオブジェクトを使用しているためだと思います)。アイテムを反復処理することでセットを初期化できることはわかっていますが、エンティティに複数のコレクションがあり、メンテナンスの問題は言うまでもなく、それは私にとってオプションではありません。

Hibernateセッションがすでに閉じられている(ドメインオブジェクトをdtosに変換する)後でコレクションにアクセスするため、これらを熱心に初期化する必要があります。

Hibernate3.5.6を使用しています。

4

3 に答える 3

17

どうやら、これは Hibernate Envers の未解決の問題です。JIRA には既に既存の問題があります: https://hibernate.atlassian.net/browse/HHH-3552。自由に投票してください。これを修正してほしいと思っている人がいることがわかったときに、物事がスピードアップするかもしれません ;)

Envers チームがこの問題を修正するまでは、私にとって有効な回避策がありsize()ます。コレクションを呼び出すと、プロキシ オブジェクトが初期化されます。

于 2012-04-05T14:04:50.730 に答える
4

Envers プロキシを初期化するためにこれまでに見つけた最善の回避策は、 Dozer を使用することです。Envers によって返された監査済みエンティティをそれ自体にマッピングすると、初期化が強制されます。

例えば:

    // Assuming you have an initialized EntityManager in entityManager & 
    // id contains your entity id..

    List<Object[]> auditList = (List<Object[]>)AuditReaderFactory.
                                   get(entityManager).
                                   createQuery().
                                   forRevisionsOfEntity(Foo.class, false, true).
                                   add(AuditEntity.id().eq(id)).
                                   getResultList();

    // Use a singleton in production apps instead...
    DozerBeanMapper mapper = new DozerBeanMapper();

    for(Object[] audit : auditList) {
        audit[0] = mapper.map(audit[0], Foo.class);
    }

    // The proxies in the Foo instances in auditList are now initialized

私はこの解決策にあまり満足していませんが、手動でコレクションに触れてプロキシを初期化するよりも好きです。誰かがより良い代替案を思い付くか、HHH-3552 が修正されることを願っています!

于 2013-05-09T21:00:55.750 に答える