Question

We have been using annotation based JPA with Hibernate as JpaVendorAdapter. We had to schedule a job to refresh an entire table data using spring scheduler. The code is as follows,

@Scheduled(fixedDelay=120000)
public void refreshTable() {

    EntityManager em = null;
    try {

        EntityManagerFactory emf = entityManager.getEntityManagerFactory();
        em = emf.createEntityManager();

        em.getTransaction().begin();

        /// do something like delete and fill table
        // this block is done for the sake of batch mode operation

        em.getTransaction().commit();

    } catch (Exception e) {
        logger.error("Failed to refresh table", e);
    } finally{
        if(em != null && em.getTransaction().isActive()){
            em.getTransaction().rollback();
            logger.info("Failure while refreshing table, rolling back transaction.");
        }
    }
}

This used to build memory utilization and caused application hang.

We added, at the end of finally block,

if(em != null){
   em.close();
}

Which solved the memory problem.

So, why does not EntityManager execute close() while being GC'ed?

Was it helpful?

Solution

The JPAConnector has various connections associated with it and it does not close all of them whereas waiting for garbage collector to do it is not a wise approach.

Closing the connections(i.e EntityManager and EntityManagerFactory) as and when they are no more needed is the best way to address this issue.

Hope this helps! Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top