Внедрение 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 каждый раз, когда я взаимодействую с базой данных.

Другие вопросы по тегам