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 を使用していません。