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

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

Теперь мне интересно, что лучше всего вводить 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. Это правильный подход к внедрению EntityManagers в Jersey+HK2?
  2. Если да, то как мне убедиться, что мои EntityManagers правильно закрыты?

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


person aioobe    schedule 29.09.2013    source источник
comment
Аналогичный вопрос задан в заголовке stackoverflow.com/questions/17396165/.   -  person ScootyPuff    schedule 19.11.2013
comment
Ага. Я проголосовал и прокомментировал этот вопрос.   -  person aioobe    schedule 19.11.2013
comment
Я использую Джерси 2.10.1, и у меня нет этой проблемы. dispose() вызывается, как и ожидалось.   -  person Thomas Wana    schedule 19.08.2014


Ответы (1)


Вместо 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;
    }
}
person ScootyPuff    schedule 25.11.2013