Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey + HK2 + Grizzly: Proper way to inject EntityManager?

I've managed to set up injection (into resource classes) of my own service classes in Jersey, HK2 and a plain GrizzlyServer. (Basically followed this example.)

I'm now curious what the best is to inject JPA EntityManagers into my resource classes? (I'm currently considering one request as one unit of work). One option that I'm currently exploring is to use a Factory<EntityManager> in the following way:

class MyEntityManagerFactory implements Factory<EntityManager> {

    EntityManagerFactory emf;

    public MyEntityManagerFactory() {
        emf = Persistence.createEntityManagerFactory("manager1");
    }

    @Override
    public void dispose(EntityManager em) {
        em.close();
    }

    @Override
    public EntityManager provide() {
        return emf.createEntityManager();
    }

}

and bind it as follows:

bindFactory(new MyEntityManagerFactory())
        .to(EntityManager.class)
        .in(RequestScoped.class);

The problem is that the dispose-method is never invoked.

My questions:

  1. Is this the right approach to injecting EntityManagers in Jersey+HK2?
  2. If so, how should I make sure my EntityManagers are closed properly?

(I'd rather not depend on heavy weight containers or an extra dependency-injection library just to cover this use case.)

like image 321
aioobe Avatar asked Sep 29 '13 18:09

aioobe


1 Answers

In place of Factory<T>.dispose(T), registering with the injectable CloseableService may do most of what you want. A Closeable adapter will be required. CloseableService closes() all registered resources upon exiting the request scope.

class MyEntityManagerFactory implements Factory<EntityManager> {
    private final CloseableService closeableService;
    EntityManagerFactory emf;

    @Inject
    public MyEntityManagerFactory(CloseableService closeableService) {
        this.closeableService = checkNotNull(closeableService);
        emf = Persistence.createEntityManagerFactory("manager1");
    }

    @Override
    public void dispose(EntityManager em) {
        em.close();
    }

    @Override
    public EntityManager provide() {
        final EntityManager em = emf.createEntityManager();
        closeableService.add(new Closeable() {
            public final void close() {
                em.close();
            }
        });
        return em;
    }
}
like image 179
ScootyPuff Avatar answered Nov 10 '22 05:11

ScootyPuff