5

JavaSE環境でのエンティティマネージャの使用に関していくつか質問があります。

リポジトリパターンを使用して、データベースでCRUD操作を実行しています。次のような基本リポジトリクラスがあります。

public class Repository<T> implements IRepository<T> {

    private EntityManager em;
    private String persistenceUnitName;

    public Repository(String persistenceUnitName) {
        this.persistenceUnitName = persistenceUnitName;
    }

    @Override
    public T find(Class<T> type, Object id) {
        return em.find(type, id);
    }

    private EntityManager getEntityManager() {
        if (this.em == null) {
            EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);

            em = emf.createEntityManager();
        }

        return em;
    }
    ...
    ...
}

次に、リポジトリを継承するEmployeeRepositoryのようなクラスがあります。これらのリポジトリクラスは、私のサービスレイヤーに作成されます。

これはエンティティマネージャーを初期化する良い方法ですか?私はそうではないと思い始めています-永続性ユニットごとに1つのエンティティマネージャーだけが必要なようですか?この場合のように、作成するリポジトリごとにエンティティマネージャーがあります...永続性ユニットごとにエンティティマネージャーが1つだけであることを確認するにはどうすればよいですか?また、エンティティマネージャとエンティティマネージャのファクトリメソッドにはcloseメソッドがあることに気付きました。これらはいつ呼び出す必要がありますか?サーバー終了イベントで?

JavaSEでのJPAの使用に関する優れた情報源をご存知の場合は、その情報をいただければ幸いです。

ありがとう!

4

2 に答える 2

4

ほとんど。永続性ユニットごとに必要なEntityManagerFactoryは1つだけです。

永続性ユニットごとにEntityManagerFactoryが1つしかないことをどのように確認しますか?

通常、開発者は、次のようなシングルトンEntityManagerFactoryを使用してヘルパークラスを作成します。

public class EntityManagerFactoryHelper {

    private static EntityManagerFactory factory;

    static {
        try {
           // Set up factory right here
        } catch(ExceptionInInitializerError e) {
            throw e;
        }
    }

    public static EntityManagerFactory getFactory() {
        return this.factory;
    }

}

一方、EntityManagerは、永続コンテキストと呼ばれる管理対象エンティティインスタンスのセットと対話するために使用されます。

ErrorInInitializerErrorを使用する理由を知りたい場合は、そのAPIが明確です

静的初期化子で予期しない例外が発生したことを通知します

..。

これはエンティティマネージャーを初期化する良い方法ですか?

さて、サービスレイヤーはトランザクション境界を区切るために使用されます。したがって、ユースケースごとに、EntityManagerを作成し、ユースケースの実行を支援するために必要な各コラボレーターの参照を渡すことができます。

public static br.com.helper.EntityManagerFactoryHelper.getFactory;

public EmployeeService {

    public void doSomething() {
        EntityManager eManager = getFactory().createEntityManager();
        eManager.getTransaction().begin();

        EmployeeRepository repository = new EmployeeRepository(eManager);

        eManager.getTransaction().commit();
    }

}

ここで、ユースケースごとに上記のボイラープレートコードが必要だと想像してください。

    public void forEachUseCase() {
        // Create an EntityManager
        // Begin a Transaction

        EmployeeRepository repository = new EmployeeRepository(eManager);

        // And finally, commit
    }

この定型コードを取り除くためにSpringに頼ることができます。

于 2010-11-01T05:56:11.487 に答える
2

ブライアン、

EntityManagerFactoryを共有することはできますが、EntityManagerを共有することはできません。JavaPersistencewikibookを参照してください。

より現代的なアプローチは、列挙型でシングルトンを実行することです。したがって、永続性ユニット名を変更することを期待しないと仮定すると(とにかく発生しないと思います)...

理想的には...

  1. 永続性ユニットごとに、EntityManagerFactoryインスタンスにシングルトンを使用します。
  2. 呼び出しごとに新しいエンティティマネージャーを作成して取得し、共有しないでください。

シングルトンメカニズムに列挙型を使用すると、次のことが可能になります...(Effective Java Second edition

  1. 簡潔であること
  2. シリアル化機構を無料で提供します
  3. 同期の問題なしにEntityManagerFactoryの複数のインスタンス化を防ぎます。これは、列挙型コンストラクターがクラスのロード時に呼び出され、コードから呼び出すことができないために発生します。
  4. プログラマーが誤った選択をしない限り、EntityManagerが共有されないようにします。
public enum PersistenceUnitFactory
{
    PERSISTENCE_UNIT_1("persistenceUnit1"),
    PERSISTENCE_UNIT_2("persistenceUnit2");

    private final EntityManagerFactory emf;
    /**
     * Maps the persistence unit name to this instance of the enum.
     *
     * @param persistenceUnitName the name of the peristence unit in
     *                            persistence.xml
     *
     * @see #getPersistenceUnitName()
     */
    PersistenceUnitFactory(final String persistenceUnitName)
    {
        emf = Persistence.createEntityManagerFactory(persistenceUnitName);
    }

    /**
     * Creates a new {@link EntityManager}.  NEVER share this across threads.
     * 
     * @return a new {@link EntityManager}
     */
    EntityManager createEntityManager()
    {
        return emf.createEntityManager();
    }
}

次に、EntityManagerを要求するのと同じくらい簡単です...

PersistenceUnitFactory.PERSISTENCE_UNIT_1.createEntityManager();

必要に応じて、永続性ユニットを追加できます。

于 2017-03-19T03:54:34.150 に答える