2012-06-27 63 views
0

我刚开始使用JPA。基于几个教程,我构建了一个简单的动态Web项目,其中包括一个GerericDAO以及一个封装了EntityManagerFactory的单例。如何构建简单的JPA/GenericDAO动态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"); 
     } 
    } 

齐心协力这个交易中的方法,我需要这样的事(让出一些细节):

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。

回答

1

JPA规范定义了一种类似于Hibernate的getCurrentSession()的模式 - 当前的EntityManager被注入到注释为@PersistenceContext的域中。

然而,规范指出,这种模式的支持,应该由外部环境,而不是由JPA供应商提供,因此,你不能只用它在独立的环境。

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

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

+0

好的,我已经看到了ThreadLocal的引用 - 我会进一步看看。关于Spring - 我对Java相当陌生,Spring对我来说显得相当陡峭的学习曲线。我正在使用Glassfish 3.1.2 - 这是否有所作为? – skyman

+0

@bugy:如果你声明你的DAO的EJB作为你应该能够使用'@ PersistenceContext'在Glassfish的 - 见,例如,http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for – axtavt

相关问题