【问题标题】:EJB 3.1 Design Woes - Need to Instantiate Stateful Beans from MDBEJB 3.1 设计难题 - 需要从 MDB 实例化有状态 Bean
【发布时间】:2012-01-05 23:30:33
【问题描述】:

我最近学到了很多关于 EJB3.1 的知识,但显然还不够。这是我的悲惨故事...

我与可以上传批处理文件的 servlet 发生争执。 servlet 验证文件,将文件数据存储在数据库中,并向队列发送已接收到新批次的消息。这一切都很好。

我有一个部署了 ejb-jar 的耳朵,它有一个 MDB,用于侦听新的批次接收到的消息。

它还有一个执行实际批处理的有状态 EJB(使用无接口视图)。 EJB 具有对无状态 JPA 实体服务 bean 的引用,因此需要进行容器管理以获取容器注入的 EntityManager。

每当 MDB 接收到消息时,我都需要创建有状态处理器 bean 的实例。我找不到任何涵盖此场景的示例/教程。

我曾尝试将有状态 bean 注入 MDB,但它不起作用:

[#|2011-11-24T13:25:45.470-0700|SEVERE|glassfish3.1.1|javax.enterprise.system.container.ejb.mdb.com.sun.ejb.containers|_ThreadID=21;_ThreadName=Thread-2;|MDB00050: Message-driven bean [MyProcessor-ear-1.0:MyMDB]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=my.package.MyMDB/myEJB,Remote 3.x interface =my.package.MyEJB,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MyEJB,refType=Session into class my.package.MyMDB: Lookup failed for 'java:comp/env/my.package.MyMDB/myEJB' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}]|#]

显然这是一种糟糕的设计方法,因为 MDB 本质上是无状态的,因此不应注入有状态的 EJB。这是有道理的。

我的问题是,当 MDB 收到消息并确保 EJB 是容器管理的时,我还能如何实例化我的有状态 EJB?

【问题讨论】:

  • 为什么 EJB 需要有状态?
  • 因为我们需要跟踪可以独立于其他批处理更改(运行、暂停、取消)的批处理状态。
  • 此外,批处理器正在处理单个批处理,因此其部分状态正在跟踪“其”批处理。

标签: dependency-injection ejb-3.1 message-driven-bean stateful-session-bean


【解决方案1】:

您可以使用 javax.jms.QueueBrowser 来检查消息在队列中的状态,您可以使用选择器和属性消息来定位具体的批处理。

【讨论】:

    【解决方案2】:

    我们重新设计了类并将它们合并,以便 MDB 的 onMessage 方法进行处理。个体批次的状态存储在 MDB 上的静态地图中。

    【讨论】:

      【解决方案3】:

      如果您需要像上面指出的那样独立于批处理(运行、暂停、取消)为批处理维护单个状态,即该状态适用于在特定时刻消耗的所有 MDB:为什么不实现EJB 作为@Singleton?这样,您可以在 EJB 中的实例变量中拥有该状态,并从中读取 MDB。

      【讨论】:

      • 该状态不适用于 MDB,它适用于给定的 EJB。 MDB 收到一条消息,表明已收到新批次并需要创建/启动处理 EJB。正在处理的 EJB 通过作为注册侦听器的另一个 MDB 接收状态更改消息。
      猜你喜欢
      • 2023-03-12
      • 2012-03-24
      • 2013-04-30
      • 2012-08-17
      • 2011-10-27
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      相关资源
      最近更新 更多