Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EntityManagerFactory is closed, Hibernate

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?

like image 753
Robert Ruxandrescu Avatar asked Feb 06 '17 10:02

Robert Ruxandrescu


1 Answers

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.

like image 69
Maciej Kowalski Avatar answered Oct 15 '22 18:10

Maciej Kowalski