-->

Upgraded from Spring 4.1.6 to 4.2.4 and suddenly g

2019-04-10 23:50发布

问题:

I have upgraded to latest Spring version from 4.1.6.Release to 4.2.4.Release and suddenly all what has functioned smoothly before, now throws the following exception.

 javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:277) ~[na:4.2.4.RELEASE]
at com.sun.proxy.$Proxy51.persist(Unknown Source) ~[na:na]

Interceptor.class

public class MessageInterceptor implements EndpointInterceptor {

    @Resource
    private SaveMessageDO saveMessageDO;

    @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint) {
     saveMessageDO.addMessage(messageContext.getRequest()));        
     return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) {
        return false;
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) {
        return false;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {

    }
}


SaveMessageDO.class
    /**
     * The entity manager.
     */
    @PersistenceContext(unitName = "xxxHibernatePersistenceUnit")
    private EntityManager entityManager;


    /**
     * Adds the message.
     *
     * @param message the message
     */
    @Transactional(value = "xyzTxManager", propagation = Propagation.REQUIRED)
    public void addMessage(final Message message) {
        entityManager.persist(message);
    }

Exception occurs in SharedEntityManagerCreator.java

else if (transactionRequiringMethods.contains(method.getName())) {
                    // We need a transactional target now, according to the JPA spec.
                    // Otherwise, the operation would get accepted but remain unflushed...
                    if (target == null || !TransactionSynchronizationManager.isActualTransactionActive()) {
                        throw new TransactionRequiredException("No EntityManager with actual transaction available " +
                                "for current thread - cannot reliably process '" + method.getName() + "' call");
                    }
                }

The method are marked with @Transaction Annotation, when i call switch back to older spring version its works fine without any issues.

Bit Background about the code, calling from Spring Webservices Interceptors to store SOAP Message in database.

回答1:

Try upgrading your version to 4.2.4 announced here: https://spring.io/blog/2015/12/17/spring-framework-4-2-4-4-1-9-released

4.2.4 addresses a few regressions in the 4.2.x line and includes many fixes and enhancements, with no immediate issues remaining. 4.2.4 is a recommended upgrade for all 4.x users now.

I think the problem your experiencing is possibly related to this question: Inconsistent JPA behavior using no transaction, propagation SUPPORTS and OpenEntityManager pattern and this bug report https://jira.spring.io/browse/SPR-13243

And in anyway, if it isn't the new version may still resolve your problem as many issues and regressions were fixed.

When getting unexpected issues that could be attributed to a framework it's always a good idea to check for any fix releases and to check their bug management system as well e.g. https://jira.spring.io/browse/SPR-13243?jql=project%20%3D%20SPR%20AND%20text%20~%20transactionrequiredexception