我是JPA和Java的新手。我理解EntityManager和EMF是如何工作的。我有JPAUtill从我获得EntityManager,它使用ThreadLocal变量,这使EntityManager线程安全。我有DAO,当我同时拥有1万个线程访问时,我会坚持新用户。
我看到以下异常:
javax.persistence.PersistenceException: org.hibernate.SessionException: Session is closed!
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
这是我的DAO代码
try{
entityManager = JPAUtil.getEntityManager();
user.setArea(getArea());
user.setCity(getCity());
user.setPassword("xxxxx");
user.setEmail_Id(getEmail_Id());
user.setMobile_Num(TempMobile_Num);
user.setFirst_Name(getFirst_Name());
user.setSession_Id("0");
user.setEmail_Verification_Status("NOT VERIFIED");
user.setBalance(new BigDecimal(0.00));
if (!entityManager.getTransaction().isActive()){
entityManager.getTransaction().begin();
}
entityManager.persist(user);
JPAUtil.commit();
} catch (Exception e) {
logger.info(e);
e.printStackTrace();
} finally{
if(entityManager.isOpen())
JPAUtil.closeEntityManager();
}
JPAUtil:
public class JPAUtil {
private static Logger logger = Logger.getLogger(JPAUtil.class);
private static EntityManager entityManager = null;
private static final ThreadLocal<EntityManager> threadLocal;
private static EntityManagerFactory emf = null;
static {
try {
emf = Persistence.createEntityManagerFactory("XYZDB");
threadLocal = new ThreadLocal<EntityManager>();
} catch (Throwable ex) {
logger.info("JPAUtil Exception", ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManager getEntityManager() {
try {
entityManager = threadLocal.get();
if (entityManager == null || !entityManager.isOpen()) {
JPAUtil.entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
} else if (!emf.isOpen()) {
entityManager = threadLocal.get();
emf = Persistence.createEntityManagerFactory("XYZDB");
JPAUtil.entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
}
} catch (Throwable ex) {
logger.info("JPAUtil Exception", ex);
throw new ExceptionInInitializerError(ex);
}
return JPAUtil.entityManager;
}
public static void closeEntityManager() {
EntityManager entityManager = threadLocal.get();
if (entityManager != null) {
entityManager.close();
threadLocal.set(null);
}
}
public static void closeEntityManagerFactory() {
emf.close();
}
public static void commit() {
if (!entityManager.getTransaction().isActive()) {
entityManager.getTransaction().begin();
}
entityManager.getTransaction().commit();
}
public static void rollback() {
if (!entityManager.getTransaction().isActive()) {
entityManager.getTransaction().begin();
}
entityManager.getTransaction().rollback();
}
}
有人可以帮我理解问题以及解决方法吗?
答案 0 :(得分:0)
从JPAUtil:
中删除此static
变量形式
private static EntityManager entityManager = null;
你还在使用static
变量;你没有真正使用ThreadLocal
。
将您的getEntityManager
更改为:
public static EntityManager getEntityManager() {
EntityManager entityManager;
try {
entityManager = threadLocal.get();
if (entityManager == null || !entityManager.isOpen()) {
entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
}
} catch (Throwable ex) {
logger.info("JPAUtil Exception", ex);
throw new ExceptionInInitializerError(ex);
}
return entityManager;
}