2017-08-14 50 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每次我與數據庫交互。