在WebSockets中通过HK2注入EnityManager

时间:2017-08-14 00:44:53

标签: java jpa entitymanager java-websocket hk2

我编写了2个WebSocket ServerEndpoints,它们使用注入的JPA EntityManager实例注入自己与数据库交互的服务。

该应用程序是部署在Tomcat服务器上的Web应用程序,使用Jersey作为JAX-RS实现,Hibernate作为JPA Provider。

有时在尝试使用内部端点时,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,但EntityManager使用不同的Binder

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端点中)。

我尝试为我的DAO中的每次访问创建一个EntityManager实例,但最后我会遇到org.hibernate.LazyInitializationExceptions,因为我的DTO需要一个开放的EntityManager(隐式)。

有关如何规避我遇到的问题的任何建议?

1 个答案:

答案 0 :(得分:0)

好的,我设法修复了我的问题,只需重写EntityManager处理,每次与数据库交互时创建和关闭EntityManager。