0

我刚刚开始使用 JPA。根据几个教程,我构建了一个简单的动态 Web 项目,其中包括一个 GerericDAO 以及一个封装 EntityManagerFactory 的单例。

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 类型的类中检索当前的 Session。我不确定如何在维护线程安全应用程序的同时使用 JPA / EntityManager 实现类似的结构?也许我的结构设计不佳 - 无论如何,任何建议/指导都非常感谢。我还没有找到一个清晰完整的例子。顺便说一句 - 我没有在这个应用程序中使用 Spring。

4

1 回答 1

1

JPA 规范定义了一个类似于 Hibernate 的模式getCurrentSession()——电流EntityManager被注入到用@PersistenceContext.

但是,规范说应该由外部环境而不是 JPA 提供者提供对这种模式的支持,因此您不能只在独立环境中使用它。

特别是,这种模式受到 Spring Framework 和 Java EE 应用程序服务器的支持。

或者,如果您不能使用 Spring Framework 或 Java EE 应用程序服务器,您可以通过将当前存储EntityManagerThreadLocal.

于 2012-06-27T09:36:58.950 回答