简体   繁体   中英

EntityManager throws TransactionRequiredException on merge() in JBoss JSF bean

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?

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.

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.

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.

只是注意:我们今天遇到了同样的问题,结果有人将EJB标记为TransactionAttributeType.NOT_SUPPORTED并将方法标记为TransactionAttributeType.REQUIRED,导致em.merge因缺少事务而失败。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM