【问题标题】:How to structure a simple JPA / GenericDAO dynamic web applicaiton如何构建一个简单的 JPA / Generic DAO 动态 Web 应用程序
【发布时间】:2012-06-27 09:21:57
【问题描述】:

我刚刚开始使用 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。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    JPA 规范定义了一个类似于 Hibernate 的 getCurrentSession() 的模式 - 当前的 EntityManager 被注入到带有 @PersistenceContext 注释的字段中。

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

    尤其是 Spring Framework 和 Java EE 应用服务器支持这种模式。

    或者,如果您不能使用 Spring Framework 或 Java EE 应用服务器,您可以通过将当前的 EntityManager 存储在 ThreadLocal 中来模拟此模式。

    【讨论】:

    • 好的,我看到了对 ThreadLocal 的引用——我会进一步研究。关于 Spring——我对 Java 还很陌生,而且 Spring 似乎(对我来说)有一个相当陡峭的学习曲线。我正在使用 Glassfish 3.1.2 - 这有什么不同吗?
    • @bugy:如果您将 DAO 声明为 EJB,您应该能够在 Glassfish 中使用 @PersistenceContext - 例如,请参阅 adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for
    猜你喜欢
    • 2015-03-31
    • 1970-01-01
    • 2019-12-17
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    相关资源
    最近更新 更多