EntityManagerFactory is closed, Hibernate

15,086

I would say that you are doing too much there.

You have to flush/commit the transaction and close the session as you are using the openSession() method of the factory.

But i dont think you need to close the SessionFactory itself

//close the SessionFactory
HibernateUtilities.getSessionFactory().close();

remove this line and you can would be able to use the factory many times.

Share:
15,086
Robert Ruxandrescu
Author by

Robert Ruxandrescu

Android and Java Software Developer.

Updated on June 24, 2022

Comments

  • Robert Ruxandrescu
    Robert Ruxandrescu almost 2 years

    I have recently created a web service that uses a static method in Java to obtain a list of items from the database.

    The web service works perfectly and returns JSON back to the caller. However, it works only once. If you try to refresh or make a new request, I get a EntityManagerFactory is closed error.

    Here's how the Web Service class looks like:

    public class WebService extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
        //obtain the list of vehicles from the database
            List<Vehicle> vehicles = ExecuteVehicle.getVehicleList();
    
            //create the Gson object and generate the Json
            Gson gson = new Gson();
            JsonElement element = gson.toJsonTree(vehicles, new TypeToken<List<Vehicle>>(){}.getType());
    
            //send the list of vehicles
            JsonArray jsonArray = element.getAsJsonArray();
            resp.setContentType("application/json");
            resp.getWriter().print(jsonArray);
        }
    }
    

    As you can see, the list of vehicles is being populated using the ExecuteVehicle.getVehicleList() method.

    Here's how that method looks like:

    public static List<Vehicle> getVehicleList(){
    
        //open a Session
        Session session = HibernateUtilities.getSessionFactory().openSession();
    
        //start a transaction
        session.beginTransaction();
    
        //SELECT STATEMENT for the entire list of Vehicles
        Query<Vehicle> query = session.getNamedQuery("SelectAllVehicles"); //query name is declared in the mapping file
        List<Vehicle> vehicles = query.list();
    
        //commit the changes and end the transaction
        session.getTransaction().commit();
    
        //close the Session
        session.close();
    
        //close the SessionFactory
        HibernateUtilities.getSessionFactory().close();
    
        return vehicles;
    }
    

    Here's the HibernateUtilities class that takes care of the Session and so on:

    public class HibernateUtilities {
        private static SessionFactory sessionFactory;
        private static StandardServiceRegistry standardServiceRegistry;
    
        static{
            try {
                //configure and build the service registry
                standardServiceRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
    
                //create the metadata
                Metadata metadata = new MetadataSources(standardServiceRegistry).getMetadataBuilder().build();
    
                //build the SessionFactory
                sessionFactory = metadata.getSessionFactoryBuilder().build();
            } catch (HibernateException e) {
                //in case the SessionFactory cannot be built, then the stackTrace is displayed
                e.printStackTrace();        
            }
        }
    
        //method that returns the Hibernate session factory
        public static SessionFactory getSessionFactory(){
            return sessionFactory;
        }
    }
    

    The question I have is - how can I avoid the EntityManagerFactory is closed error. Furthermore, I will have to obtain this list again and again, in a real time manner. Is that feasible with Hibernate? To obtain a list of items from a database in a real-time manner (say, every 2 seconds or so)? I know this depends on the number of items and so on, but I'm asking from a technical standpoint - from what I understand, opening and closing the Session takes a long time - could I do this over and over again in the same Session and if so, how?