目前我正在尝试删除ConversationScoped有状态会话Bean(SFSB). ConversationScope由CDI容器管理,SFSB的生命周期由EJB容器管理.它是否正确?
在我的控制器中,我试图通过调用SFSB的方法结束对话并调用@Remove带注释的方法来销毁SFSB.
谈话可以没有任何问题结束,但我无法破坏SFSB.
Weld参考指南(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)
root cause06002
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)
有任何想法吗?
谢谢
最佳答案 您应结束CDI对话,CDI将调用@Remove方法.
看看Weld文档:
“
有状态会话bean可以定义一个删除方法,注释为@Remove,应用程序使用该方法指示应该销毁实例.但是,对于bean的上下文实例 – 在CDI控制下的实例 – 如果bean具有范围@Dependent,则此方法只能由应用程序调用.对于具有其他范围的bean,应用程序必须让容器销毁bean.
“