【问题标题】:CDI WELD @ConversationScoped @Stateful EJB conversation.end() & @Remove SFSBCDI WELD @ConversationScoped @Stateful EJB conversation.end() & @Remove SFSB
【发布时间】:2011-05-10 13:14:56
【问题描述】:

目前我正在尝试删除 ConversationScoped Stateful Session Bean (SFSB)。 ConversationScope 由 CDI 容器管理,SFSB 的生命周期由 EJB 容器管理。这是正确的吗?

在我的控制器中,我试图通过调用 SFSB 的方法来结束对话并调用 @Remove 注释方法来销毁 SFSB。

对话可以毫无问题地结束,但我无法破坏 SFSB。

焊接参考指南 (WELD Conversation Scope) 中的代码示例:

@ConversationScoped @Stateful
public class OrderBuilder {

   private Order order;
   private @Inject Conversation conversation;
   private @PersistenceContext(type = EXTENDED) EntityManager em;

   @Produces public Order getOrder() {
      return order;
   }


   public Order createOrder() {
      order = new Order();
      conversation.begin();
      return order;
   }

   public void addLineItem(Product product, int quantity) {
      order.add(new LineItem(product, quantity));
   }


   public void saveOrder(Order order) {
      em.persist(order);
      conversation.end();
   }

   @Remove
   public void destroy() {}

}

控制器:

@Named
@SessionScoped
public class TestController implements Serializable{

  @Inject
  private OrderBuilder orderBuilder;

  ...

  public String checkout(Order order){
    orderBuilder.saveOrder(order);
    orderBuilder.destroy();
    return "success";
  }
}

在我调用 testController.checkout(order) 之后,我得到了这个异常:

javax.servlet.ServletException: java.lang.reflect.InvocationTargetException javax.faces.webapp.FacesServlet.service(FacesServlet.java:321) org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67) 根本原因

javax.faces.el.EvaluationException:

java.lang.reflect.InvocationTargetException javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:98) com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98) javax.faces.component.UICommand.broadcast(UICommand.java:311) javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781) javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246) com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77) com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97) com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114) javax.faces.webapp.FacesServlet.service(FacesServlet.java:308) org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)

有什么想法吗?

谢谢

【问题讨论】:

    标签: ejb cdi jboss-weld


    【解决方案1】:

    您应该结束 CDI 对话,CDI 将调用 @Remove 方法。

    查看 Weld 文档: " 有状态会话bean 可以定义一个remove 方法,注释为@Remove,应用程序使用它来指示一个实例应该被销毁。但是,对于 bean 的上下文实例(受 CDI 控制的实例),只有当 bean 具有 @Dependent 范围时,应用程序才能调用此方法。对于具有其他作用域的 bean,应用程序必须让容器销毁 bean。 "

    【讨论】:

      【解决方案2】:

      JSF 1.2 或 2.0 不支持带参数的方法等表达式 obj.method(参数) JSF 只支持没有参数的方法 obj.method() Seam 2,3 build in 支持这种表达式,但如果你只使用焊接(CDI 支持接缝,接缝核心)而没有其他接缝罐,你就不能拥有这种能力。 但是有可能把这种能力赋予JSF。 将此添加到 jar 项目中,您可以使用带参数的方法。如果您使用的是 maven,您可以使用下面的代码或。在 lib 文件夹中手动下载 jars。

           <dependency>
              <groupId>javax.el</groupId>
              <artifactId>el-api</artifactId>
              <version>2.2</version>
          </dependency>
          <dependency>
              <groupId>org.glassfish.web</groupId>
              <artifactId>el-impl</artifactId>
              <version>2.2</version>
          </dependency>
      

      此外,我用 tomcat 测试它工作正常,但在码头中与其他 jar 发生了一些冲突。可能是关于我的项目。

      将此添加到 web xml

      <context-param>
              <param-name>com.sun.faces.expressionFactory</param-name>
              <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
      </context-param>
      

      【讨论】:

      • 我不知道除了接缝 3 中的一个罐子外,哪个罐子提供了这种能力。您可以在没有这些 jar 的情况下添加它。
      猜你喜欢
      • 2013-04-18
      • 2011-12-24
      • 2016-02-14
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多