JEE7 @Transactional annotation not always fires

橙三吉。 提交于 2021-01-28 23:40:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!