Java EntityManager 在 JBoss JSF bean 中的 merge() 上抛出 TransactionRequiredException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1084627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:24:38  来源:igfitidea点击:

EntityManager throws TransactionRequiredException on merge() in JBoss JSF bean

javajsfjpajbossentitymanager

提问by Kosi2801

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.

我在 JBoss 5.0.1GA 上设置了一个 JSF 应用程序,以在表中显示用户列表,并允许通过每个用户旁边的按钮删除单个用户。

When deleteUser is called, the call is passed to a UserDAOBean which gets an EntityManager injected from JBoss.

当 deleteUser 被调用时,调用被传递给一个 UserDAOBean,它从 JBoss 中获取一个 EntityManager。

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.

删除用户(代码是来自 JPA 教程的 c&p)。只是调用 em.remove(entity) 没有效果,仍然会导致相同的异常。

When this line is reached, I'm getting a TransactionRequiredException:

当到达这一行时,我收到一个 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)

...

...

20:38:06,406 错误 [[Faces Servlet]] Servlet Faces Servlet 的 Servlet.service() 抛出异常 javax.persistence.TransactionRequiredException:EntityManager 必须在 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.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.

我已经尝试在它周围包装一个手动管理的事务(em.getTransaction().begin() + .commit()),但这失败了,因为它在 JBoss 容器中是不允许的。我也没有成功使用 UserTransaction。在网上搜索这个问题也没有找到类似的案例和解决方案。

Has anyone experienced something similar before and found a solution to this?

有没有人以前经历过类似的事情并找到了解决方案?

采纳答案by Kosi2801

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.

这确实是一个丢失的事务,但解决方案不是使用 EntityManager 来处理它,而是添加一个注入的 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.

感谢所有以某种方式超过 100 个角落导致此解决方案的建议。

回答by Kosi2801

Are you sure that you annotated you bean with @Stateless or register it with xml?

你确定你用 @Stateless 注释了你的 bean 还是用 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.

但这似乎很奇怪,因为如果您没有明确设置,这是默认值。

回答by chinto

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.

这就是我们在所有@Stateful bean 中使用的内容。

If you are using Seam, you can also use @Transactional(TransactionPropagationType.REQUIRED)annotation.

如果你使用 Seam,你也可以使用@Transactional(TransactionPropagationType.REQUIRED)注解。

回答by jwenting

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.

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