2

JPA 1、Struts2.3.1、Google-App-Enging 1.7.0を使用しています

私のコミックでは、ゲッターとセッターを使用して以下のプロパティがあります。

@ManyToOne(fetch=FetchType.LAZY, targetEntity=User.class)
private User user = null;

JPAクエリの私の方法:

public Comics readComics(int random, String url){
    EntityManager em = EMF.get().createEntityManager();
    Comics comics = null;

    try{
        Query q = em.createNamedQuery("Comics.getComics");
        q.setParameter("random", random);
        q.setParameter("url", url);
        comics = (Comics) q.getSingleResult();

    } catch(NoResultException ex){
        System.out.println("ERROR CATCHED: " + ex.getMessage());
        comics = null;
    } finally{
        em.close();
    }

    return comics;
}

私の見解では、私は持っています:

<s:property value="comics.user.userName"/>

userNameその場合はアクセスできませんが、エンティティマネージャが閉じていない場合userNameは表示されます。

正しいものはどれでしょう?削除してもよろしいem.close()ですか?

=======================

を使用しBeanUtils.copyProperties て、以下のコードも試しました:

Comics emComics = (Comics) q.getSingleResult();
BeanUtils.copyProperties(comics, emComics);
BeanUtils.copyProperties(comics.getUser(), emComics.getUser());

正しい使い方copyPropertiesですか?削除BeanUtils.copyProperties(comics.getUser(), emComics.getUser());すると、再び表示されなくなりますuser

4

1 に答える 1

2

em.close() を削除するのはよくありません。削除すると、接続リークが発生します。プール内のすべての接続が使い果たされると、アプリケーションは動作を停止します。

簡単な修正は、em.close() を呼び出す前に、jsp が必要とするすべてのものが初期化されていることを確認することです。

プロバイダーとして hibernate を使用している場合は、Hibernate.initialize() を使用できます。

public Comics readComics(int random, String url){
    EntityManager em = EMF.get().createEntityManager();
    Comics comics = null;
   try{
        Query q = em.createNamedQuery("Comics.getComics");
        q.setParameter("random", random);
        q.setParameter("url", url);
        comics = (Comics) q.getSingleResult();

        Hibernate.initialize(comics.getUser());

    } catch(NoResultException ex){
        System.out.println("ERROR CATCHED: " + ex.getMessage());
        comics = null;
    } finally{
        em.close();
    }

    return comics;
}

他のプロバイダーを使用している場合は、同等のメソッドを探すか、オブジェクトのプロパティの 1 つを取得してプロキシの初期化をトリガーする独自の関数を作成することができます。

もう 1 つのオプションは、結合フェッチを使用してクエリを変更し、コミックのフェッチ中にユーザー アソシエーションをフェッチすることです。

これに対する正しい解決策は、エンティティ マネージャーを簡単に処理するためのソリューションを提供する Spring または EJB を使用することです。クエリごとに新しい entityManager を開くというアプローチは最適ではありません。理想的には、トランザクションごとまたはリクエスト全体に対して 1 つの entityManager にする必要があります。遅延初期化例外、OpenSessionInViewFilter などについて読んでください。

于 2012-09-11T02:11:59.590 に答える