问题
For several days I'm trying to manage with JPA transactions after moving to WildFly 8 server and JEE7 and I cannot understand why in some cases @Transactional (javax.transaction.Transactional) annotation doesn't intercept method annotated with it. I cannot see any rule why sometimes it works and sometimes not.
Example of my not working code:
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.faces.view.ViewScoped;
import com.i4u.app.domain.AppDomain;
import com.i4u.app.mail.ComMailForm;
import javax.transaction.Transactional;
import com.i4u.qla.action.company.CmpFunctions;
import com.i4u.qla.model.invoice.Invoice;
@Named
@ViewScoped
public class InvMailForm extends ComMailForm<Invoice> {
private static final long serialVersionUID = 1L;
@Inject
private AppDomain ad;
@Inject
private CmpFunctions cf;
@Inject
private InvEmailFunctions invEmail;
@Inject
private EntityManager entityManager;
@Override
public void sendMail(String type) {
if (type.equals("invoice")) {
sendInvoice();
inst = null;
}
}
/**
* Method sends invoice and marks it as printed
*/
private void sendInvoice() {
try {
invEmail.sendQlaInvoicePDFFile(inst, getSubject(), getContent(), getSendTo(), getBccTo());
// sent invoice should be marked as printed
printed();
msg.message(msg.get("msg.Successful"), msg.get("msg.InvoiceWillBeSent"));
} catch (Exception e) {
msg.fatalMessage(msg.get("msg.Failed"), msg.get("msg.FailedToSendInvoice"));
e.printStackTrace();
}
setSendTo(null);
setBccTo(null);
}
public void sendPrepare(Invoice inv) {
super.sendPrepare(inv);
setSendTo(cf.getInvoiceEmail(inst.getCompany()));
setSubject(inst.getCompanyName() + " - "
+ ad.getCompany().getName() + " week " + inst.getCweek());
}
/**
* Method sets invoice as printed
*/
@Transactional
private void printed() {
inst = entityManager.find(Invoice.class, inst.getId());
inst.setPrinted(true);
// on the line below exception is thrown
entityManager.merge(inst);
entityManager.flush();
}
}
In this case on sendEmail("invoice") execution application fails on instance merging in printed() method with exception:
11:20:36,199 ERROR [stderr] (default task-1) javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
11:20:36,199 ERROR [stderr] (default task-1) at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:855)
11:20:36,200 ERROR [stderr] (default task-1) at org.jboss.as.jpa.container.AbstractEntityManager.merge(AbstractEntityManager.java:553)
11:20:36,200 ERROR [stderr] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:20:36,200 ERROR [stderr] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
11:20:36,200 ERROR [stderr] (default task-1) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:20:36,200 ERROR [stderr] (default task-1) at java.lang.reflect.Method.invoke(Method.java:606)
11:20:36,200 ERROR [stderr] (default task-1) at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:412)
11:20:36,201 ERROR [stderr] (default task-1) at org.jboss.weld.bean.builtin.CallableMethodHandler.invoke(CallableMethodHandler.java:42)
11:20:36,201 ERROR [stderr] (default task-1) at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
11:20:36,201 ERROR [stderr] (default task-1) at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100)
11:20:36,201 ERROR [stderr] (default task-1) at org.jboss.weldx.persistence.EntityManager$863717792$Proxy$_$$_Weld$Proxy$.merge(Unknown Source)
11:20:36,201 ERROR [stderr] (default task-1) at com.i4u.qla.action.invoice.InvMailForm.printed(InvMailForm.java:78)
11:20:36,201 ERROR [stderr] (default task-1) at com.i4u.qla.action.invoice.InvMailForm.sendInvoice(InvMailForm.java:54)
11:20:36,202 ERROR [stderr] (default task-1) at com.i4u.qla.action.invoice.InvMailForm.sendMail(InvMailForm.java:42)
11:20:36,202 ERROR [stderr] (default task-1) at com.i4u.qla.action.invoice.InvMailForm$Proxy$_$$_WeldSubclass.sendMail(Unknown Source)
11:20:36,202 ERROR [stderr] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:20:36,202 ERROR [stderr] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
11:20:36,202 ERROR [stderr] (default task-1) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:20:36,202 ERROR [stderr] (default task-1) at java.lang.reflect.Method.invoke(Method.java:606)
11:20:36,203 ERROR [stderr] (default task-1) at org.jboss.weld.interceptor.proxy.SimpleInterceptionChain.interceptorChainCompleted(SimpleInterceptionChain.java:51)
11:20:36,203 ERROR [stderr] (default task-1) at org.jboss.weld.interceptor.chain.AbstractInterceptionChain.invokeNextInterceptor(AbstractInterceptionChain.java:96)
11:20:36,203 ERROR [stderr] (default task-1) at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:43)
11:20:36,203 ERROR [stderr] (default task-1) at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:36)
11:20:36,203 ERROR [stderr] (default task-1) at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:51)
11:20:36,203 ERROR [stderr] (default task-1) at com.i4u.qla.action.invoice.InvMailForm$Proxy$_$$_WeldSubclass.sendMail(Unknown Source)
11:20:36,204 ERROR [stderr] (default task-1) at com.i4u.qla.action.invoice.InvMailForm$Proxy$_$$_WeldClientProxy.sendMail(Unknown Source)
11:20:36,204 ERROR [stderr] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:20:36,204 ERROR [stderr] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
11:20:36,204 ERROR [stderr] (default task-1) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:20:36,205 ERROR [stderr] (default task-1) at java.lang.reflect.Method.invoke(Method.java:606)
11:20:36,205 ERROR [stderr] (default task-1) at javax.el.ELUtil.invokeMethod(ELUtil.java:326)
11:20:36,205 ERROR [stderr] (default task-1) at javax.el.BeanELResolver.invoke(BeanELResolver.java:536)
11:20:36,205 ERROR [stderr] (default task-1) at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
11:20:36,205 ERROR [stderr] (default task-1) at com.sun.el.parser.AstValue.invoke(AstValue.java:269)
11:20:36,205 ERROR [stderr] (default task-1) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
11:20:36,205 ERROR [stderr] (default task-1) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
11:20:36,206 ERROR [stderr] (default task-1) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
11:20:36,206 ERROR [stderr] (default task-1) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
11:20:36,206 ERROR [stderr] (default task-1) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
11:20:36,206 ERROR [stderr] (default task-1) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
11:20:36,206 ERROR [stderr] (default task-1) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
11:20:36,207 ERROR [stderr] (default task-1) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
11:20:36,207 ERROR [stderr] (default task-1) at javax.faces.component.UICommand.broadcast(UICommand.java:315)
11:20:36,207 ERROR [stderr] (default task-1) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
11:20:36,207 ERROR [stderr] (default task-1) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
11:20:36,207 ERROR [stderr] (default task-1) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
11:20:36,207 ERROR [stderr] (default task-1) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
11:20:36,208 ERROR [stderr] (default task-1) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
11:20:36,208 ERROR [stderr] (default task-1) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
11:20:36,208 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
11:20:36,208 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
11:20:36,208 ERROR [stderr] (default task-1) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:98)
11:20:36,208 ERROR [stderr] (default task-1) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:56)
11:20:36,209 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
11:20:36,209 ERROR [stderr] (default task-1) at com.i4u.app.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:37)
11:20:36,209 ERROR [stderr] (default task-1) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:56)
11:20:36,209 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
11:20:36,209 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
11:20:36,209 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)
11:20:36,210 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
11:20:36,210 ERROR [stderr] (default task-1) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
11:20:36,210 ERROR [stderr] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
11:20:36,210 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113)
11:20:36,210 ERROR [stderr] (default task-1) at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52)
11:20:36,210 ERROR [stderr] (default task-1) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)
11:20:36,210 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61)
11:20:36,211 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
11:20:36,211 ERROR [stderr] (default task-1) at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
11:20:36,211 ERROR [stderr] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
11:20:36,211 ERROR [stderr] (default task-1) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
11:20:36,211 ERROR [stderr] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
11:20:36,212 ERROR [stderr] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
11:20:36,212 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240)
11:20:36,212 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
11:20:36,212 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73)
11:20:36,212 ERROR [stderr] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146)
11:20:36,212 ERROR [stderr] (default task-1) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168)
11:20:36,213 ERROR [stderr] (default task-1) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687)
11:20:36,213 ERROR [stderr] (default task-1) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
11:20:36,213 ERROR [stderr] (default task-1) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
11:20:36,213 ERROR [stderr] (default task-1) at java.lang.Thread.run(Thread.java:744)
In other places similar codes works fine.
What cases can avoid @Transactional interceptor (or any interceptor) fireing?
I will be glad for any clue to find root cause. Now, after several days I'm sitting, crying and I really have no idea which way to follow.
回答1:
Declare the public accesible method (sendMail()
) as @Transactional.
The @Transactional
anotation is supported by a CDI interceptor, and thus, only methods called by "client" classes are intercepted (this is, mostly public or protected methods, and called from another class).
So, if the sendMail
is not invoked in a transactional context, the merge
operation called at merge fails.
More info on CDI Interceptors:
- http://docs.jboss.org/cdi/spec/1.0/html/interceptors.html
- http://docs.oracle.com/javaee/6/tutorial/doc/gkhjx.html
来源:https://stackoverflow.com/questions/23194777/jee7-transactional-annotation-not-always-fires