0

JPAを使い始めたばかりです。いくつかのチュートリアルに基づいて、GerericDAO と EntityManagerFactory をカプセル化するシングルトンを含む単純な動的 Web プロジェクトを作成しました。

public class PersistenceManager {
    private static final PersistenceManager instance = new PersistenceManager();
    protected EntityManagerFactory emf;
    public static PersistenceManager getInstance() {
        return instance;
    }
    private PersistenceManager() {
    }
    public EntityManagerFactory getEntityManagerFactory() {
        if (emf == null)
            createEntityManagerFactory();
        return emf;
    }
    public void closeEntityManagerFactory() {
        if (emf != null) {
            emf.close(); emf = null;
        }
    }
    protected void createEntityManagerFactory() {
        this.emf = Persistence.createEntityManagerFactory("Fusion");
    }
}



public class GenericJPADAO<ID extends Serializable, T> implements GenericDAO<ID, T> {
    private Class<T> persistentClass;
        private EntityManager entityManager;

    @SuppressWarnings("unchecked")
    public GenericJPADAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    protected EntityManager getEntityManager() {
        if (entityManager == null)
            throw new IllegalStateException("EntityManager has not been set on DAO before");
        return entityManager;
    }
    public T create(T element) throws IOException, IllegalArgumentException {
        if (element == null)
            throw new IllegalArgumentException();
        try {
            getEntityManager().persist(element); 
            return element;
        } catch (Exception e) {
            throw new IOException("create failed");
        }
    }

これを Transaction メソッドでまとめるには、次のようなものが必要です (詳細の一部は省略します)。

DAOFactory factory = DAOFactory.instance(DAOFactory.JPA);
ConfigurationDAO dao = factory.getAddressDAO();
dao.setEntityManager(entityManager);
EntityTransaction ut = entityManager.getTransaction();      
try {
    ut.begin();
    dao.create(address);
    ut.commit();
} catch (Exception e) {
    ut.rollback();
}
    finally {
 close??
}

私はこれに非常に慣れていませんが、Transaction メソッドから DAO クラスに EntityManager を設定するのは面倒です。以前に Hibernate を使用したことがあり、私の DAO クラスは HibernateUtil 型クラスから現在のセッションを取得できました。スレッドセーフなアプリケーションを維持しながら、JPA / EntityManager で同様の構造を実現する方法がわかりませんか? たぶん私の構造はうまく設計されていません - とにかくアドバイス/ガイダンスは大歓迎です。これの明確な完全な例を見つけることができませんでした。ところで、このアプリケーションでは Spring を使用していません。

4

1 に答える 1

1

JPA 仕様では、Hibernate と同様のパターンが定義されています。getCurrentSession()電流EntityManagerは、 で注釈が付けられたフィールドに注入されます@PersistenceContext

ただし、仕様では、このパターンのサポートは JPA プロバイダーではなく外部環境によって提供される必要があると規定されているため、スタンドアロン環境でのみ使用することはできません。

特に、このパターンは Spring Framework および Java EE アプリケーション サーバーでサポートされています。

または、Spring Framework または Java EE アプリケーション サーバーを使用できない場合は、現在の を に格納することで、このパターンをエミュレートできEntityManagerますThreadLocal

于 2012-06-27T09:36:58.950 に答える