简体   繁体   中英

@Retryable with JPA create problems

Following this post I'm trying to implement the save() method of my Invoice bean using @Retryable in order to make my application more solid. I'm using Spring JPA + Hibernate.

I've an inteface for my service:

@RemoteDestination
@DataEnabled
 @PreAuthorize("hasAnyRole('AMMINISTRATORE','CAPO_SERVIZIO','UTENTE','CONTABILITA')")
public interface FatturaCustomRepository {

@Retryable(backoff = @Backoff(delay = 200, multiplier = 2, random = true), maxAttempts = 5)
public <S extends Fattura> S save(S invoice) throws Exception;
}

and this is the implementation:

@Override
@Transactional
public <S extends Fattura> S save(S invoice) throws Exception {
    log.debug("public <S extends Fattura> S salva(S fattura, List<Long> idVendite)");

        int anno = LocalDate.now().getYear();           
        String sQuery = "SELECT MAX(numero) FROM Fattura WHERE YEAR(data) = :anno ";
        Query q = manager.createQuery(sQuery);
        q.setParameter("anno", anno);
        Integer maxNum = 0;
        try {
            maxNum = (Integer) q.getSingleResult();
            log.debug("Numero trovato: " + maxNum);
            if (maxNum == null)
                maxNum = 0;
        } catch (NoResultException e) {             
            maxNum = 0;
        } catch (Exception e) {             
            maxNum = 0;
        }
        int numeroFattura = maxNum + 1 ;            
        invoice.setNumero(numeroFattura);       


         if (fattura.isNew())
             manager.persist(invoice);
         else
             manager.merge(invoice);

        return invoice;
    }
}

Simulating an error (duplicated fiscal number) I see in the log that Spring try to redo the transaction but seems something is wrong with Hibernate session.

 04/08/2015 14:13:38,475 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - public <S extends Fattura> S salva(S fattura, List<Long> idVendite)
04/08/2015 14:13:38,483 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
04/08/2015 14:13:38,497 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Numero trovato: 4
04/08/2015 14:13:38,497 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Fattura n. 4
04/08/2015 14:13:38,894 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - public <S extends Fattura> S salva(S fattura, List<Long> idVendite)
04/08/2015 14:13:38,895 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
04/08/2015 14:13:38,906 ERROR qtp10588730-13 FatturaCustomRepositoryImpl:102 - 
04/08/2015 14:13:38,906 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Fattura n. 0
04/08/2015 14:13:39,441 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - public <S extends Fattura> S salva(S fattura, List<Long> idVendite)
04/08/2015 14:13:39,442 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
04/08/2015 14:13:39,445 ERROR qtp10588730-13 FatturaCustomRepositoryImpl:102 - 
04/08/2015 14:13:39,445 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Fattura n. 0
04/08/2015 14:13:40,436 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - public <S extends Fattura> S salva(S fattura, List<Long> idVendite)
04/08/2015 14:13:40,437 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
04/08/2015 14:13:40,439 ERROR qtp10588730-13 FatturaCustomRepositoryImpl:102 - 
04/08/2015 14:13:40,440 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Fattura n. 0
04/08/2015 14:13:42,686 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - public <S extends Fattura> S salva(S fattura, List<Long> idVendite)
04/08/2015 14:13:42,687 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
04/08/2015 14:13:42,689 ERROR qtp10588730-13 FatturaCustomRepositoryImpl:102 - 
04/08/2015 14:13:42,690 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Fattura n. 0
04/08/2015 14:13:42,691 ERROR qtp10588730-13 TestServiceImpl:114 - 
java.lang.IllegalStateException: There are delayed insert actions before operation as cascade level 0.
    at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsBeforeOperation(SessionImpl.java:652) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:809) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at com.sun.proxy.$Proxy243.persist(Unknown Source) ~[?:?]
    at it.pianetatecno.aci.servicesimpl.FatturaCustomRepositoryImpl.salva(FatturaCustomRepositoryImpl.java:116) ~[aci-java-1.7.6.jar:1.7.6]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:68) ~[spring-security-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:74) ~[spring-retry-1.1.2.RELEASE.jar:?]
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:263) ~[spring-retry-1.1.2.RELEASE.jar:?]
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:154) ~[spring-retry-1.1.2.RELEASE.jar:?]
    at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:101) ~[spring-retry-1.1.2.RELEASE.jar:?]
    at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:118) ~[spring-retry-1.1.2.RELEASE.jar:?]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at com.sun.proxy.$Proxy254.salva(Unknown Source) ~[?:?]
    at it.pianetatecno.aci.servicesimpl.TestServiceImpl.inserimentoVendita(TestServiceImpl.java:112) [aci-java-1.7.6.jar:1.7.6]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) [spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:68) [spring-security-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) [spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) [spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) [spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at com.sun.proxy.$Proxy273.inserimentoVendita(Unknown Source) [?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45]
    at org.granite.messaging.service.ServiceInvocationContext.invoke(ServiceInvocationContext.java:72) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.service.security.AbstractSecurityService.endAuthorization(AbstractSecurityService.java:108) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.spring.security.SpringSecurity3Service.authorize(SpringSecurity3Service.java:292) [granite-server-spring-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.service.ServiceInvoker.invoke(ServiceInvoker.java:220) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.amf.process.AMF3MessageProcessor.processRemotingMessage(AMF3MessageProcessor.java:141) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.amf.process.AMF3MessageProcessor.process(AMF3MessageProcessor.java:60) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.amf.process.AMF0MessageProcessor.process(AMF0MessageProcessor.java:79) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.webapp.AMFEndpoint.serviceJMFAMF(AMFEndpoint.java:151) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.messaging.webapp.AMFEndpoint.service(AMFEndpoint.java:64) [granite-server-core-3.1.2-SNAPSHOT.jar:?]
    at org.granite.spring.ServerFilter.handle(ServerFilter.java:331) [granite-server-spring-3.1.2-SNAPSHOT.jar:?]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) [spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) [spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [javax.servlet-api-3.1.0.jar:3.1.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:806) [jetty-servlet-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [jetty-servlet-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224) [websocket-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [jetty-servlet-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:550) [jetty-security-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1128) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1062) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:113) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.Server.handle(Server.java:507) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:237) [jetty-server-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:240) [jetty-io-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:93) [jetty-io-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:53) [jetty-io-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceRun.produceAndRun(ExecuteProduceRun.java:191) [jetty-util-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceRun.run(ExecuteProduceRun.java:126) [jetty-util-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:641) [jetty-util-9.3.0.M2.jar:9.3.0.M2]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:559) [jetty-util-9.3.0.M2.jar:9.3.0.M2]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]

and this strange errors happears in the console:

    04/08/2015 14:13:40,437 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
ago 04, 2015 2:13:40 PM org.hibernate.AssertionFailure <init>
ERROR: HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in it.pianetatecno.aci.domain.fatture.Fattura entry (don't flush the Session after an exception occurs)
04/08/2015 14:13:40,439 ERROR qtp10588730-13 FatturaCustomRepositoryImpl:102 - 
04/08/2015 14:13:40,440 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Fattura n. 0
04/08/2015 14:13:42,686 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - public <S extends Fattura> S salva(S fattura, List<Long> idVendite)
04/08/2015 14:13:42,687 DEBUG qtp10588730-13 FatturaCustomRepositoryImpl:90 - Anno da cercare: 2015
ago 04, 2015 2:13:42 PM org.hibernate.AssertionFailure <init>
ERROR: HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in it.pianetatecno.aci.domain.fatture.Fattura entry (don't flush the Session after an exception occurs)

Spring retry should not be transparent to the rest of the application? Where is the problem in the code?

Thanks

I solved adding a

entityManager.clear();

at the top of the method

public <S extends Fattura> S save(S invoice)

Not sure this is the best way but I not found anything else useful to solve this problem!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM