通过WebSockets中的HK2进行EnityManager注入 [英] EnityManager Injection via HK2 in WebSockets

查看:163
本文介绍了通过WebSockets中的HK2进行EnityManager注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了2个WebSocket ServerEndpoint,它们使用JPA EntityManager的注入实例来注入与数据库交互的服务.

I have written 2 WebSocket ServerEndpoints that inject Services that themselves interact with the Database using injected instances of the JPA EntityManager.

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

The application is a web application deployed on a Tomcat Server, using Jersey as JAX-RS implementation and Hibernate as JPA Provider.

有时候,当尝试在数据库内部端点中关闭EntityManager时,会发生这种情况.另外,我担心我可能会生成触发内存泄漏的代码.

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.

这是我正在使用的自定义ServerEndpoint.Configurator(基于 https://gist.github .com/facundofarias/7102f5120944c462a5f77a17f295c4d0 ):

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;
    }
}

在应用程序的其余部分中,我对EntityManager使用相同的ServicesBinder,但使用不同的Binder.

In the rest of the application I am using the same ServicesBinder, but a different Binder for the 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端点中).

It is loaded with the Scope RequestScoped (only there, not in the WebSocket Endpoints).

我尝试为DAO中的每次访问创建一个EntityManager实例,但是由于我的DTO需要一个打开的EntityManager(隐式),所以最终我会遇到org.hibernate.LazyInitializationExceptions.

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?

推荐答案

好吧,我设法通过重写EntityManager处理程序来每次与数据库进行交互时创建并关闭EntityManager来解决此问题.

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.

这篇关于通过WebSockets中的HK2进行EnityManager注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆