0

The below code give me the org.hibernate.HibernateException: The internal connection pool has reached its maximum size and no connection is currently available!. This error shows that I am not closing the transaction and since I have connection pool size set to 20, it gives the error when all connections are consumed. Below is the code:

public class XxspAsnOutHeaderRepo {
public static Logger logger = Logger.getLogger(XxspAsnOutHeaderRepo.class);

private EntityManager entityManager = JPAUtil.getEntityManagerFactory().createEntityManager();
private EntityTransaction transaction = entityManager.getTransaction();

public List<XxspAsnOutHeaderEntity> getOneOutHeaderWithFlag(String flag) {
    TypedQuery<XxspAsnOutHeaderEntity> query = null;
    try {
        if (!transaction.isActive())
            transaction.begin();
        logger.info("getting headers from Database..... ");
        query = entityManager.createNamedQuery(XxspAsnOutHeaderEntity.FIND_ALL_HEADERS_FLAG_SIX, XxspAsnOutHeaderEntity.class)
                                .setParameter("proc_flag", flag).setMaxResults(1);

    } catch (PersistenceException ex) {
        logger.error("Error occured while fetching data from DataBase...\n", ex);
        throw ex;
    } finally {
        if (transaction.getRollbackOnly())
            transaction.rollback();         
    }
    return query.getResultList(); 

  }
} 

The test case:

 @Test    
 public void testConnectionPoolLimit(){
      for(int i=1; i<30; i++){
          new XxspAsnOutHeaderRepo().getOneOutHeaderWithFlag("6");
      }
 }

The above code fails after 20 select statements. But when I delete the if (!transaction.isActive()) transaction.begin(); , the codes runs fine and create 30 read operations. And this time with improved speed.
The above also runs if I write transaction.commit(); statement at last. But performance is slow.

Is it the case that transaction is not required for Read operations?

The Coder
  • 3,447
  • 7
  • 46
  • 81
  • No. The proper fix would be to get an EntityManager from the method, get a transaction from the method, and close everything at the end of the method, in a finally block. Your Repo shouldn't have those fields. They should be local variables of the method. – JB Nizet Jan 19 '18 at 09:06
  • And what would be the purpose of that? how is that going to help? – The Coder Jan 19 '18 at 19:21
  • It will make sure you close the resources that need to be closed when you don't need them anymore, instead of leaving them open, and thus prevent all the other threads from getting a connection. And it will make your repository thread-safe. – JB Nizet Jan 19 '18 at 19:53

0 Answers0