問(wèn)題描述
在代碼中利用Jpa自定義了update語(yǔ)句,比如下面的addAge方法:
@Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {
@Query(value = "update tb_student set age = age + 1 where 1 = 1 ", nativeQuery = true)
@Modifying
void addAge();
}
執(zhí)行此方法時(shí)吴裤,會(huì)報(bào)如下錯(cuò)誤:
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:398) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1581) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$ModifyingExecution.doExecute(JpaQueryExecution.java:263) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
拋出javax.persistence.TransactionRequiredException: Executing an update/delete query 異常
原因分析
我們根據(jù)異常中的這句話
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1581)
找到了AbstractProducedQuery中的executeUpdate方法:
public int executeUpdate() throws HibernateException {
getProducer().checkTransactionNeededForUpdateOperation( "Executing an update/delete query" );
beforeQuery();
try {
return doExecuteUpdate();
}
catch ( QueryExecutionRequestException e) {
throw new IllegalStateException( e );
}
catch( TypeMismatchException e ) {
throw new IllegalArgumentException( e );
}
catch ( HibernateException e) {
throw getExceptionConverter().convert( e );
}
finally {
afterQuery();
}
}
進(jìn)入第一句話的checkTransactionNeededForUpdateOperation方法:
default void checkTransactionNeededForUpdateOperation(String exceptionMessage) {
if ( !isTransactionInProgress() ) {
throw new TransactionRequiredException( exceptionMessage );
}
}
可以看到枢析,在執(zhí)行update語(yǔ)句前朝刊,JPA會(huì)判斷當(dāng)前語(yǔ)句是不是處于一個(gè)事務(wù)中墨微,若不在事務(wù)中,則會(huì)拋出TransactionRequiredException異常恤溶。
問(wèn)題解決
根據(jù)以上分析,要解決這個(gè)問(wèn)題很簡(jiǎn)單帜羊,讓代碼運(yùn)行在事務(wù)中即可咒程。在要執(zhí)行的addAge方法上面加上@Transactional注解,問(wèn)題解決讼育。
@Query(value = "update tb_student set age = age + 1 where 1 = 1 ", nativeQuery = true)
@Modifying
@Transactional
void addAge();