2017-08-14 88 views
0

我已经编写了2个WebSocket ServerEndpoints,它们使用注入的JPA EntityManager实例注入自己与数据库交互的服务。EnityManager通过WebSockets中的HK2注入

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

有时会发生EntityManager在试图访问端点内部的DB 时关闭。另外我担心我可能会产生触发内存泄漏的代码。

这是自定义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的端点)。

我想在我的DAO,每次访问创建EntityManager实例,但后来因为我的DTO需要一个开放的EntityManager(隐含的)我会碰上org.hibernate.LazyInitializationExceptions最终。

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

+0

'bindFactory(EntityManagerFactory.class).to(EntityManager.class);' - 尝试明确设置范围。默认范围是服务的Singeleton,而不是RequestScope。另外,不可能为服务提供多个实现或工厂。 –

回答

0

好吧,我设法解决我的问题,只需重写EntityManager处理来创建和关闭EntityManager每次我与数据库交互。