Jersey, Guice и Hibernate - безопасность потоков EntityManager
Я использовал этот урок так же, как в моем приложении:http://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/
Мое приложение - веб-сервис JAX-RS, который будет получать много одновременных запросов и обновлять базу данных.
Реализация GenericDAOImpl.java:
public class GenericDAOImpl<T> implements GenericDAO<T> {
@Inject
protected EntityManager entityManager;
private Class<T> type;
public GenericDAOImpl(){}
public GenericDAOImpl(Class<T> type) {
this.type = type;
}
@Override
public void save(T entity) {
entityManager.getTransaction().begin();
entityManager.persist(entity);
entityManager.getTransaction().commit();
}
}
Если 2 одновременных потока пытаются сохранить сущность, я получаю
java.lang.IllegalStateException: Transaction already active
Сохранение работает хорошо, если я прокомментирую транзакцию.
Я пытался использовать
@Inject
protected Provider<EntityManager> entityManagerProvider;
или же
@Inject
protected EntityManagerFactory entityManagerProvider;
и для каждого запроса:
EntityManager entityManager = entityManagerProvider.get()
Но тогда я получаю:
org.hibernate.PersistentObjectException: detached entity passed to persist
Как правильно реализовать универсальный класс DAO для инъекций и потоков, безопасный для Guice + Hibernate EntityManager?
ОБНОВИТЬ
Эндрю Рейнер комментарий отhttp://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/
«Логика на самом деле не готова к работе - по крайней мере, если она используется в веб-приложении.
Пул соединений Hibernates очень прост и не готов к работе - рекомендуется использовать пул источников данных, например c3p0.
EntityManager не должен использоваться повторно - он предназначен для создания для каждой транзакции / запроса. Существует большая вероятность загрязнения последующих запросов.
Там также нет отката транзакции, если что-то пойдет не так.
Интересный подход - но для веб-приложений было бы гораздо безопаснее использовать собственный модуль расширения Persist от Guices для управления жизненным циклом экземпляров и транзакций EntityMananger ».