title: How to make DAO thread safe JPA?
body: <p>I am new to JPA and Java. I understood how EntityManager and EMF works a littel bit. I have JPAUtill from where I get EntityManager, which is using ThreadLocal variable, which makes EntityManager thread safe. I have DAO where in I am persisting new users when having 10 thousand thread accesses simultaneously.</p>
  
  <p>I get to see following exception:</p>
  
  <pre><code>javax.persistence.PersistenceException: org.hibernate.SessionException: Session is closed!
          at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
  </code></pre>
  
  <p>Here is my DAO code</p>
  
  <pre><code>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();
  }
  </code></pre>
  
  <p>JPAUtil:</p>
  
  <pre><code>public class JPAUtil {
  
      private static Logger logger = Logger.getLogger(JPAUtil.class);
      private static EntityManager entityManager = null;
      private static final ThreadLocal&lt;EntityManager&gt; threadLocal;
  
      private static EntityManagerFactory emf = null;
  
      static {
          try {
              emf = Persistence.createEntityManagerFactory("XYZDB");
              threadLocal = new ThreadLocal&lt;EntityManager&gt;();
          } 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();
      }
  }
  </code></pre>
  
  <p>Can someone please help me understand the issue and how to resolve it?</p>