问题
I've set up a JSF application on JBoss 5.0.1GA to present a list of Users in a table and allow deleting of individual users via a button next to each user.
When deleteUser is called, the call is passed to a UserDAOBean which gets an EntityManager injected from JBoss.
I'm using the code
public void delete(E entity)
{
em.remove(em.merge(entity));
}
to delete the user (code was c&p from a JPA tutorial). Just calling em.remove(entity) has no effect and still causes the same exception.
When this line is reached, I'm getting a TransactionRequiredException:
(skipping apparently irrelevant stacktrace-stuff)
...
20:38:06,406 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction at org.jboss.jpa.deployment.ManagedEntityManagerFactory.verifyInTx(ManagedEntityManagerFactory.java:155) at org.jboss.jpa.tx.TransactionScopedEntityManager.merge(TransactionScopedEntityManager.java:192) at at.fhj.itm.utils.DAOImplTemplate.delete(DAOImplTemplate.java:54) at at.fhj.itm.UserBean.delete(UserBean.java:53) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
I already tried to wrap a manually managed transaction (em.getTransaction().begin() + .commit() ) around it, but this failed because it is not allowed within JBoss container. I had no success with UserTransaction either. Searches on the web for this issue also turned up no similar case and solution.
Has anyone experienced something similar before and found a solution to this?
回答1:
Found the missing link.
It was indeed a missing transaction but the solution was not to use the EntityManager to handle it but to add an injected UserTransaction.
@Resource
UserTransaction ut;
...
public void delete(E entity)
{
ut.begin();
em.remove(em.merge(entity));
ut.commit();
}
Thanks to all suggestions which somehow over 100 corners lead to this solution.
回答2:
Know this is an old question, but just in case somebody stumbles on this like me.
Try
em.joinTransaction();
em.remove(bean);
em.flush();
That's what we use in all our @Stateful beans.
If you are using Seam, you can also use @Transactional(TransactionPropagationType.REQUIRED)
annotation.
回答3:
Are you sure that you annotated you bean with @Stateless or register it with xml?
Try add transaction's annotation to you code, this can help you:
@TransactionAttribute(REQUIRED)
public void delete(E entity)
{
em.remove(em.merge(entity));
}
But it seems strange, because this is default value if you don't set it explicitly.
回答4:
just a note: we ran into this same issue today, turned out someone had marked the EJB as TransactionAttributeType.NOT_SUPPORTED AND the method as TransactionAttributeType.REQUIRED, causing the em.merge to fail for lack of transaction.
来源:https://stackoverflow.com/questions/1084627/entitymanager-throws-transactionrequiredexception-on-merge-in-jboss-jsf-bean