2012-06-27 145 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

相關問題