问题
I have written 2 WebSocket ServerEndpoints that inject Services that themselves interact with the Database using injected instances of the JPA EntityManager.
The application is a web application deployed on a Tomcat Server, using Jersey as JAX-RS implementation and Hibernate as JPA Provider.
Sometimes it happens that the EntityManager is closed when trying to the DB inside the Endpoints. Also I fear I might have produced code that triggers a Memory Leak.
This is the custom ServerEndpoint.Configurator
that I am using (based on https://gist.github.com/facundofarias/7102f5120944c462a5f77a17f295c4d0):
public class Hk2Configurator extends ServerEndpointConfig.Configurator {
private static ServiceLocator serviceLocator;
public Hk2Configurator() {
if (serviceLocator == null) {
serviceLocator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
ServiceLocatorUtilities.bind(serviceLocator, new ServicesBinder()); // binds the "normal" Services that interact with the DB
ServiceLocatorUtilities.bind(serviceLocator, new AbstractBinder() {
@Override
protected void configure() {
bindFactory(EntityManagerFactory.class).to(EntityManager.class);
}
});
}
}
@Override
public <T> T getEndpointInstance(final Class<T> endpointClass) throws InstantiationException {
T endpointInstance = super.getEndpointInstance(endpointClass);
serviceLocator.inject(endpointInstance);
return endpointInstance;
}
}
In the rest of the application I am using the same ServicesBinder
, but a different Binder
for the EntityManager.
The EntityManagerFactory
looks like this:
public class EntityManagerFactory implements Factory<EntityManager> {
private static final javax.persistence.EntityManagerFactory FACTORY = Persistence.createEntityManagerFactory("PersistenceUnit");
@Override
public final EntityManager provide() {
return FACTORY.createEntityManager();
}
@Override
public final void dispose(final EntityManager instance) {
instance.close();
}
}
It is loaded with the Scope RequestScoped
(only there, not in the WebSocket Endpoints).
I tried creating an EntityManager
instance for every access in my DAOs, but then I would run into org.hibernate.LazyInitializationExceptions
eventually since my DTOs need an open EntityManager
(implicitly).
Any suggestions on how to circumvent the issues I'm having?
回答1:
Okay, I managed to fix my issue by simply rewriting the EntityManager handling to create and close an EntityManager every time I interact with the database.
来源:https://stackoverflow.com/questions/45666129/enitymanager-injection-via-hk2-in-websockets