Jersey + HK2 + Grizzly:注入EntityManager的正确方法是什么?

时间:2013-09-29 18:43:04

标签: jpa dependency-injection jersey grizzly hk2

我设法在Jersey,HK2和一个简单的GrizzlyServer中设置我自己的服务类的注入(进入资源类)。 (基本上遵循this example。)

我现在很好奇将JPA EntityManagers注入我的资源类最好的是什么? (我目前正在考虑将一个请求作为一个工作单元)。我目前正在探索的一个选项是以下列方式使用Factory<EntityManager>

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

}

并按如下方式绑定它:

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

问题是永远不会调用dispose - 方法。

我的问题:

  1. 这是在Jersey + HK2中注入EntityManagers的正确方法吗?
  2. 如果是这样,我该如何确保我的EntityManagers正确关闭?
  3. (我宁愿不依赖于重量级容器或额外的依赖注入库来覆盖这个用例。)

1 个答案:

答案 0 :(得分:6)

代替Factory<T>.dispose(T),注册注射CloseableService可能会完成您想要的大部分工作。将需要Closeable适配器。退出请求范围时,CloseableService closes()所有注册资源。

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