Jersey, Guice e Hibernate - segurança de threads do EntityManager

Eu usei este tutorial da mesma maneira no meu aplicativo:http://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/

Meu aplicativo é um serviço da web JAX-RS que receberá muitas solicitações simultâneas e fará atualizações no banco de dados.

Implementação de 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();
    }

}

Se 2 threads simultâneos tentarem salvar a entidade, eu recebo

java.lang.IllegalStateException: Transaction already active

Salvar funciona bem se eu comentar a transação.

Eu tentei usar

@Inject
protected Provider<EntityManager> entityManagerProvider;

ou

@Inject
protected EntityManagerFactory entityManagerProvider;

e para cada solicitação:

EntityManager entityManager = entityManagerProvider.get()

Mas então eu recebo:

org.hibernate.PersistentObjectException: detached entity passed to persist

Qual é a maneira correta de implementar a classe DAO genérica de injeção / thread-safe do Guice + Hibernate EntityManager?

ATUALIZAR

Andrew Rayner comenta dehttp://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/

"A lógica não está pronta para a produção - pelo menos se usada em um aplicativo da web.

O conjunto de conexões do Hibernates é muito básico e não está pronto para produção - a recomendação é usar um conjunto de fontes de dados como c3p0.

O EntityManager não deve ser reutilizado - ele deve ser criado por transação / solicitação. Há uma boa chance de poluir solicitações subsequentes.

Também não há reversão de transação se algo der errado.

Uma abordagem interessante - mas seria muito mais seguro para os webapps usar o módulo de extensão Persist do Guices para gerenciar o ciclo de vida das instâncias e transações do EntityMananger ".

questionAnswers(3)

yourAnswerToTheQuestion