CDI WELD @ConversationScoped @Stateful EJB conversation.end()& @Remove SFSB

时间:2011-05-10 13:14:57

标签: ejb cdi jboss-weld

目前我正在尝试删除ConversationScoped有状态会话Bean(SFSB)。 ConversationScope由CDI容器管理,SFSB的生命周期由EJB容器管理。这是对的吗?

在我的Controller中,我试图通过调用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)

有什么想法吗?

THX

2 个答案:

答案 0 :(得分:3)

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

查看Weld文档: “ 有状态会话bean可以定义一个删除方法,注释为@Remove,应用程序使用该方法指示应该销毁实例。但是,对于bean的上下文实例 - 在CDI控制下的实例 - 如果bean具有范围@Dependent,则此方法只能由应用程序调用。对于具有其他范围的bean,应用程序必须让容器销毁bean。 “

答案 1 :(得分:-1)

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

     <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工作正常,但在码头一些冲突发生在其他罐子。可能是我的项目。

将此添加到web xml

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