Внедрение EnityManager через HK2 в WebSockets
Я написал 2 WebSocket ServerEndpoints, которые внедряют Сервисы, которые сами взаимодействуют с Базой данных, используя внедренные экземпляры JPA EntityManager.
Приложение представляет собой веб-приложение, развернутое на сервере Tomcat, использующее Джерси в качестве реализации JAX-RS и Hibernate в качестве поставщика JPA.
Иногда случается, что EntityManager закрывается при попытке доступа к БД внутри конечных точек. Также я боюсь, что мог создать код, который вызывает утечку памяти.
Это обычай ServerEndpoint.Configurator
что я использую (на основе 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;
}
}
В остальной части приложения я использую то же самое ServicesBinder
, но другой Binder
для EntityManager.
EntityManagerFactory
выглядит так:
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();
}
}
Загружен с прицеломRequestScoped
(только там, а не в конечных точках WebSocket).
Я пытался создать EntityManager
экземпляр для каждого доступа в моих DAO, но тогда я столкнулся бы с org.hibernate.LazyInitializationExceptions
в конце концов, так как мои DTO нуждаются в открытом EntityManager
(Неявно).
Любые предложения о том, как обойти проблемы, которые у меня возникают?
1 ответ
Хорошо, мне удалось решить мою проблему, просто переписав обработку EntityManager, чтобы создавать и закрывать EntityManager каждый раз, когда я взаимодействую с базой данных.