One option is to instead of creating a new EntityManagerFactory
in the EMFactory
(which is in a request scope), you could create a singleton factory for the EntityManagerFactory
, then just inject the EntityManagerFactory
into the EMFactory
.
public class EMFFactory implements Factory<EntityManagerFactory> {
private final EntityManagerFactory emf;
public EMFFactory (){
emf = Persistence.createEntityManagerFactory(persistenceUnit);
}
public EntityManagerFactory provide() {
return emf;
}
...
}
public class EMFactory implements Factory<EntityManager> {
private final EntityManager em;
@Inject
public EMFactory (EntityManagerFactory emf){
em = emf.createEntityManager();
}
public EntityManager provide() {
return em;
}
...
}
Haven't tested this exact implementation out, but it should look something like this. I've used this pattern before.
register(new AbstractBinder() {
@Override
public void configure() {
bindFactory(EMFFactory.class).to(EntityManagerFactory.class).in(Singleton.class);
bindFactory(EMFactory.class).to(EntityManager.class).in(RequestScoped.class);
}
});
UPDATE
One thing to note about the above example is that it doesn't clean up resources, i.e. the EntityManager
should be close; it won't close itself. There is a dispose
method in the Factory
class that we need to override, but from my experience, this is never called by Jersey.
What we can do is add the EntityManager
to a [CloseableService
][1]
public class EMFactory implements Factory<EntityManager> {
private final EntityManagerFactory emf;
private final CloseableService closeService;
@Inject
public EMFactory (EntityManagerFactory emf, CloseableService closeService){
this.emf = emf;
this.closeService = closeService;
}
public EntityManager provide() {
final EntityManager em = emf.createEntityManager();
this.closeService.add(new Closeable(){
@Override
public void close() {
em.close();
}
});
return em;
}
...
}
This way the EntityManager
is ensured to be closed at the end of the request.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…