我刚开始使用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。
好的,我已经看到了ThreadLocal的引用 - 我会进一步看看。关于Spring - 我对Java相当陌生,Spring对我来说显得相当陡峭的学习曲线。我正在使用Glassfish 3.1.2 - 这是否有所作为? – skyman
@bugy:如果你声明你的DAO的EJB作为你应该能够使用'@ PersistenceContext'在Glassfish的 - 见,例如,http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for – axtavt