JEE7 @Transactional注释并非总是会触发 [英] JEE7 @Transactional annotation not always fires

查看:76
本文介绍了JEE7 @Transactional注释并非总是会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在转移到WildFly 8服务器和JEE7之后的几天里,我一直在尝试使用JPA事务进行管理,但我不明白为什么在某些情况下@Transactional(javax.transaction.Transactional)注释不会截获带有注释的方法.我看不到任何规则为何有时有效而有时无效.

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.

我的无效代码示例:

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();
    }

}

在这种情况下,在sendEmail("invoice")上,执行应用程序在实例合并到print()方法中时失败,但例外:

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.

哪些情况下可以避免@Transactional拦截器(或任何拦截器)触发?

我很高兴能找到根本原因的任何线索. 现在,几天后,我坐在那里哭泣,我真的不知道该怎么走.

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.

推荐答案

将公共可访问方法(sendMail())声明为@Transactional.

Declare the public accesible method (sendMail()) as @Transactional.

CDI拦截器支持@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).

因此,如果未在事务上下文中调用sendMail,则在合并时调用的merge操作将失败.

So, if the sendMail is not invoked in a transactional context, the merge operation called at merge fails.

有关CDI拦截器的更多信息:

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

这篇关于JEE7 @Transactional注释并非总是会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆