英文:
Getting "javax.persistence.TransactionRequiredException: no transaction is in progress" in Spring Boot Application
问题
我在我的Spring Boot应用程序中使用了JPA+Hibernate。我的服务方法如下所示:
@Override
public Employee createEmployee(Employee employeeModel) {
logger.debug("进入createEmployee方法");
Optional<Employee> optionalEmployee = repository.findByEmpShortNm(employeeModel.getEmpShortNm());
logger.debug("获取可选的员工");
if (optionalEmployee.isPresent())
return optionalEmployee.get();
else {
logger.debug("持久化员工......");
return repository.save(employeeModel);
}
}
EmployeeRepository.java 有以下方法:
@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<Employee> findByEmpShortNm(String uuid);
在我在存储库方法上应用了Lock
注解之前,我的应用程序运行正常。但是在应用了Lock
后,createEmployee
方法抛出以下异常:
javax.persistence.TransactionRequiredException: 没有进行中的事务
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1560)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1581)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:111)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:196)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
为什么它无法获取事务,而在不使用@Lock
注解时正常运行?@Lock
和事务之间有什么关系?
如果有相关参考资料,我将不胜感激。
英文:
I am using JPA+Hibernate in my Spring Boot Application. My Service Method is as follows:-
@Override
public Employee createEmployee(Employee employeeModel) {
logger.debug("entered the createEmployee method");
Optional<Employee> optionalEmployee = repository.findByEmpShortNm(employeeModel.getEmpShortNm());
logger.debug("Fetched the optional");
if(optionalEmployee.isPresent())
return optionalEmployee.get();
else {
logger.debug("Persisting employee.....");
return repository.save(employeeModel);
}
}
EmployeeRepository.java has following method:-
@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<Employee> findByEmpShortNm(String uuid);
My Application was working fine until I applied Lock annotation
on my repository method. After applying Lock
createEmployee method is throwing following exception:-
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1560)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1581)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:111)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:196)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
Why it's not able to get a transaction while it was working fine when I was not using @Lock
Annoation. What's the relation b/w @Lock and Transaction.
I would appreciate if any reference can be provided.
答案1
得分: 3
解决方案:您应该在您的服务上加上@Transactional
注解。
当锁被显式启用且没有活动的事务时,底层的JPA实现将抛出
TransactionRequiredException
异常。
当您没有自己的事务时,为什么要锁定实体对象似乎是合乎逻辑的呢?在您想要锁定实体对象的仓库方法之外,应该有一个事务。
阅读这篇文章:
https://www.baeldung.com/java-jpa-transaction-locks
英文:
Solution: you should annotate your service with @Transactional
> When the lock is explicitly enabled and there is no active
> transaction, the underlying JPA implementation will throw a
> TransactionRequiredException.
It is somehow logical when you don't have your own transaction, why do you want to lock the entity object? You should have a transaction outside repository method during which, you want to lock entity object.
Read this article:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论