CDI WELD @ConversationScoped @Stateful EJB conversation.end() & @删除SFSB
目前我正在尝试删除 ConversationScoped Stateful Session Bean (SFSB)。 ConversationScope 由 CDI 容器管理,SFSB 的生命周期由 EJB 容器管理。这是正确的吗?
在我的控制器中,我尝试通过调用 SFSB 的方法来结束对话,并调用 @Remove 带注释的方法来销毁 SFSB。
对话可以毫无问题地结束,但我无法摧毁 SFSB。
Weld 参考指南 (WELD对话范围):
@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.InitationTargetException javax.faces.webapp.FacesServlet.service(FacesServlet.java:321) org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67) 根本原因
javax.faces.el.EvaluationException:
java.lang.reflect.InitationTargetException 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)
有什么想法吗?
谢谢
currently i am trying to remove a ConversationScoped Stateful Session Bean (SFSB). The ConversationScope is managed by the CDI Container and the lifecycle of the SFSB is managed by the EJB Container. Is this correct?
In my Controller i'm trying to end the conversation by calling a method of the SFSB and to call the @Remove annotated method to destroy the SFSB.
The conversation can be end without any problems but i am not able to destroy the SFSB.
A Code example from Weld Reference Guide (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() {}
}
The controller:
@Named
@SessionScoped
public class TestController implements Serializable{
@Inject
private OrderBuilder orderBuilder;
...
public String checkout(Order order){
orderBuilder.saveOrder(order);
orderBuilder.destroy();
return "success";
}
}
After i have called testController.checkout(order), i'am getting this exception:
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 causejavax.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)
Any ideas?
THX
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您应该结束 CDI 对话,CDI 将调用 @Remove 方法。
查看焊接文档:
”
有状态会话 Bean 可以定义一个删除方法(注释为 @Remove),应用程序使用该方法来指示应销毁实例。然而,对于 bean 的上下文实例(CDI 控制下的实例),只有当 bean 具有 @Dependent 作用域时,应用程序才能调用此方法。对于其他作用域的bean,应用程序必须让容器销毁该bean。
”
You should end the CDI conversation and CDI will call the @Remove method.
Have a look in Weld documentation :
"
Stateful session beans may define a remove method, annotated @Remove, that is used by the application to indicate that an instance should be destroyed. However, for a contextual instance of the bean—an instance under the control of CDI—this method may only be called by the application if the bean has scope @Dependent. For beans with other scopes, the application must let the container destroy the bean.
"
JSF 1.2 或 2.0 不支持带有参数的类似表达式的方法
obj.method(参数)
JSF 仅支持不带参数的方法,例如
obj.method()
Seam 2,3 内置支持这种表达方式,但如果您仅使用焊接(CDI 支持接缝、接缝核心)而没有其他接缝罐,则无法拥有此功能。
但将这种能力赋予 JSF 是可能的。
将其添加到 jar 项目中,您可以使用带参数的方法。如果您使用 Maven,您可以使用下面的代码或。手动下载 jar 到 lib 文件夹中。
另外,我用 tomcat 测试它工作正常,但在 jetty 中与其他 jar 发生了一些冲突。可能是关于我的项目。
将其添加到 web xml
JSF 1.2 or 2.0 does not support expression like methods with parameter
obj.method(parameter)
JSF supoorts only method without parameter like
obj.method()
Seam 2,3 build in supports this kind of expreesions but if you are using only weld (CDI support of seam, core of seam) without other seam jars, you can not have this ability.
But it is possible to give this kind of ability to JSF.
Adding this to jar project you can use methods with parameters. If you are using maven u can use code below or. Download jars manually in lib folder.
Additionally, I tested it with tomcat worked fine, but in jetty some conflicts happen with the other jars. May be it is about my project.
Add this to web xml