0

I am new to Spring and trying to use Transactions. I am using spring-boot-starter-data-jpa 2.7.3. My code is like this:

@Transactional(rollbackFor = { SQLException.class }) // https://www.baeldung.com/transaction-configuration-with-jpa-and-spring
    private void update(Bookings_V01 b) {
        ... some code here ...
        Aggregates agg = aggregatesRepository.lockForUpdate(sav, pid, g);
... some code here ...
    }
public interface AggregatesRepository extends CrudRepository<Aggregates, Integer> {
 
    // https://www.baeldung.com/java-jpa-transaction-locks#:~:text=To%20specify%20a%20lock%20on,FROM%20Customer%20c%20WHERE%20c.
    // When the lock is explicitly enabled and there is no active transaction, the
    // underlying JPA implementation will throw a TransactionRequiredException.
    // https://docs.oracle.com/javaee/7/api/javax/persistence/LockModeType.html
    @Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
    @Query("select a from Aggregates a WHERE a.sav = :sav and a.pid = :pid and a.Period = :period")                                    
    Aggregates lockForUpdate(String sav, String pid, Period period);
}

When this code is run I see following message:

2022-09-14 17:39:13.248 TRACE 18401 --- [nio-8080-exec-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.lockForUpdate]: This method is not transactional.

and then this exception:

2022-09-14 17:39:13.285 ERROR 18401 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress] with root cause

javax.persistence.TransactionRequiredException: no transaction is in progress
        at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1644)
        at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
        at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1665)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:406)
        at jdk.proxy4/jdk.proxy4.$Proxy148.getSingleResult(Unknown Source)
        at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:198)
        at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:90)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:156)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:144)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:160)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:139)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
        at jdk.proxy4/jdk.proxy4.$Proxy129.lockForUpdate(Unknown Source)
        at cdao.dpde.controllers.MainController.update(MainController.java:114)

How can I fix this? This link says

if we're using a Spring Boot project and have a spring-data-* or spring-tx dependencies on the classpath, then transaction management will be enabled by default.

as I am using spring-boot-starter-data-jpa I have not done anything extra to enable transaction manager. below is dependency tree of spring-boot-starter-data-jpa:

+- org.springframework.boot:spring-boot-starter-data-jpa:jar:2.7.3:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:2.7.3:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:5.3.22:compile
[INFO] |  |  \- org.aspectj:aspectjweaver:jar:1.9.7:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:2.7.3:compile
[INFO] |  |  +- com.zaxxer:HikariCP:jar:4.0.3:compile
[INFO] |  |  \- org.springframework:spring-jdbc:jar:5.3.22:compile
[INFO] |  +- jakarta.transaction:jakarta.transaction-api:jar:1.3.3:compile
[INFO] |  +- jakarta.persistence:jakarta.persistence-api:jar:2.2.3:compile
[INFO] |  +- org.hibernate:hibernate-core:jar:5.6.10.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.4.3.Final:compile
[INFO] |  |  +- net.bytebuddy:byte-buddy:jar:1.12.13:compile
[INFO] |  |  +- antlr:antlr:jar:2.7.7:compile
[INFO] |  |  +- org.jboss:jandex:jar:2.4.2.Final:compile
[INFO] |  |  +- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] |  |  +- org.hibernate.common:hibernate-commons-annotations:jar:5.1.2.Final:compile
[INFO] |  |  \- org.glassfish.jaxb:jaxb-runtime:jar:2.3.6:compile
[INFO] |  |     +- org.glassfish.jaxb:txw2:jar:2.3.6:compile
[INFO] |  |     +- com.sun.istack:istack-commons-runtime:jar:3.0.12:compile
[INFO] |  |     \- com.sun.activation:jakarta.activation:jar:1.2.2:runtime
[INFO] |  +- org.springframework.data:spring-data-jpa:jar:2.7.2:compile
[INFO] |  |  +- org.springframework.data:spring-data-commons:jar:2.7.2:compile
[INFO] |  |  +- org.springframework:spring-orm:jar:5.3.22:compile
[INFO] |  |  +- org.springframework:spring-context:jar:5.3.22:compile
[INFO] |  |  +- org.springframework:spring-tx:jar:5.3.22:compile
[INFO] |  |  \- org.springframework:spring-beans:jar:5.3.22:compile
[INFO] |  \- org.springframework:spring-aspects:jar:5.3.22:compile
morpheus
  • 18,676
  • 24
  • 96
  • 159
  • 1
    You cannot use transactional on private methods - [see here](https://stackoverflow.com/questions/4396284/does-spring-transactional-attribute-work-on-a-private-method) – johnnyutts Sep 15 '22 at 05:06

0 Answers0