从JBoss 7迁移到WildFly 9时使用CMT的EJB

7

我正在将我的应用程序从 JBoss 7 迁移到 WildFly(v9.0.1),但由于 bean 事务管理错误,它无法部署。

    Caused by: javax.naming.NamingException: WFLYNAM0062: Failed to lookup env/com.component.eventmgt.EventServiceImpl/transaction [Root exception is java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:157)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
    ... 90 more
Caused by: java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:319)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:143)
    ... 95 more
Caused by: javax.naming.NameNotFoundException: UserTransaction [Root exception is java.lang.IllegalStateException: WFLYEJB0137: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:153)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
    ... 96 more

以下是EventServiceImpl类的内容。

    @Stateless
    @Remote(EventService.class)
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public class EventServiceImpl implements EventService {

        /**
         * Logger
         */
        private static Logger log = LoggerFactory.getLogger(EventService.class);

        private EventTableDAO eventDao;

        @PersistenceContext(unitName = "SOMF-GT")
        private EntityManager entityManager;

        @Resource
        private UserTransaction transaction;

       public List<Map> loadEvents() throws EventsException {

        Configuration configurationEntry = new Configuration();
        try {
            Map configuration = configurationService.getConfiguration();
            if (configuration != null) {

        eventDao = new EventTableDAO(Event.class, entityManager, transaction);
        List<Map> eventsMapList = new ArrayList();
}
}

我知道如果我将事务管理更改为BMT,并使用@TransactionManagement(TransactionManagementType.BEAN),则会出现以下错误

WFLYJPA0060:需要事务才能执行此操作(使用事务或扩展持久性上下文)

我想知道为什么我们首先要更改这个?

有任何信息,请告诉我!


1
我认为这个限制(在javax.ejb.TransactionManagementType.CONTAINER中使用EJB的UserTransaction)在JBoss 7中不存在。 - Marco
1个回答

4
这些变化在Wildfly 8中推出,基于EJB 3.1标准化全局JNDI名称空间(如下所述)。来自Wildfly 8 开发人员指南的说明如下:
引入了标准化的全局JNDI名称空间和一系列相关名称空间,这些名称空间映射到Java EE应用程序的各种作用域。用于可移植JNDI查找的三个JNDI名称空间是java:global、java:module和java:app。如果您在应用程序中使用JNDI查找,则需要更改它们以遵循新的标准化JNDI名称空间约定。
为符合新的可移植JNDI名称空间规则,您需要审查JNDI名称空间规则并修改应用程序代码以遵循这些规则。
该指南进一步指出:
WildFly 8加强了对JNDI命名空间名称的限制,为应用服务器中绑定的每个名称提供可预测和一致的规则,并防止未来的兼容性问题。这意味着,如果您的应用程序当前的命名空间不遵循新规则,则可能会遇到问题。
下面是表格中关于UserTransaction的JNDI映射示例 以前版本中JNDI映射的示例及其现在的样子 的一部分:
Previous Namespace          New Namespaces
------------------          --------------
java:comp/UserTransaction   java:comp/UserTransaction (This will not be accessible for non EE threads, e.g. Threads your application directly creates)
java:comp/UserTransaction   java:jboss/UserTransaction (Globally accessible, use this if java:comp/UserTransaction is not available)

关于 WFLYEJB0137 的编辑:

这只是一种理论构想,可能毫无价值 - 如果有问题,请告诉我,我会删除它。Java EE 6 教程 - 容器管理的事务 中提到:

使用容器管理的事务划分的企业 bean 也不能使用 javax.transaction.UserTransaction 接口。

进一步地:

(事务) Required 属性

如果客户端正在运行一个事务并调用企业 bean 的方法,则该方法在客户端的事务中执行。如果客户端未与事务相关联,则容器在运行该方法之前启动一个新事务。

对于使用容器管理的事务划分运行的所有企业 bean 方法来说,Required 属性是隐式的事务属性。通常情况下,您不需要设置 Required 属性,除非您需要覆盖另一个事务属性。由于事务属性是声明性的,因此您可以轻松地稍后更改它们。

异常消息几乎已经说明了一切:

WFLYEJB0137:只允许具有 bean 管理的事务划分的会话和消息驱动 bean 访问 UserTransaction

你的 EJB 使用容器管理事务 (CMT) 划分,这与 bean 管理事务 (BMT) 划分不兼容,UserTransaction 就在其中。
关于切换到 BMT 和

WFLYJPA0060: 需要事务才能执行此操作(使用事务或扩展持久性上下文)

我发现 需要事务才能执行此操作(使用事务或扩展持久性上下文),它似乎表明事务应该由您管理,正如 @Marco 在评论中所指出的那样。看起来您已经做出了适当的修改。

使用“java:jboss/UserTransaction”命名空间时,我遇到了以下错误:WFLYNAM0059注入资源查找失败:java:jboss/UserTransaction(Wildfly 9)。 - Marco
1
@Marco 你指的是哪个版本的9呢?是9.0.0.Final、9.0.1.Final还是9.0.2.Final? - Jon Sampson
目前我已将TransactionManagementType从CONTAINER转换为BEAN,并手动管理UserTransaction。9.0.2.Final。 - Marco
1
@Marco,你的WFLYNAM0059是否有基本异常WFLYEJB0137,就像问题中提到的那样? - Jon Sampson
是的,WFLYEJB0137。 - Marco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接