Джерси + 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
-метод никогда не вызывается.
Мои вопросы:
- Это правильный подход к введению EntityManager в Джерси +HK2?
- Если так, как я должен убедиться, что мои EntityManager закрыты должным образом?
(Я бы предпочел не зависеть от тяжеловесных контейнеров или дополнительной библиотеки внедрения зависимостей только для того, чтобы покрыть этот вариант использования.)
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;
}
}