Джерси + HK2 + Grizzly: правильный способ введения EntityManager?

Мне удалось настроить внедрение (в классы ресурсов) моих собственных классов обслуживания в Джерси, HK2 и обычном GrizzlyServer. (В основном следовал этому примеру.)

Теперь мне любопытно, как лучше внедрить JPA EntityManager в мои классы ресурсов? (В настоящее время я рассматриваю один запрос как одну единицу работы). Один из вариантов, который я сейчас изучаю, - это использовать 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. Это правильный подход к введению EntityManager в Джерси +HK2?
  2. Если так, как я должен убедиться, что мои EntityManager закрыты должным образом?

(Я бы предпочел не зависеть от тяжеловесных контейнеров или дополнительной библиотеки внедрения зависимостей только для того, чтобы покрыть этот вариант использования.)

1 ответ

Решение

На месте Factory<T>.dispose(T), регистрируясь с инъекционным CloseableService может делать большинство того, что вы хотите. Closeable потребуется адаптер. CloseableServicecloses() все зарегистрированные ресурсы при выходе из области запроса.

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;
    }
}
Другие вопросы по тегам