问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/42065877/entitymanagerfactory-is-closed-hibernate