gpt4 book ai didi

java - Spring boot + Hibernate + JPA 没有可用的事务性 EntityManager

转载 作者:IT老高 更新时间:2023-10-28 13:57:00 27 4
gpt4 key购买 nike

我使用 Spring Boot 1.2.3.RELEASE 版本和 JPA over hibernate。我遇到以下异常

org.springframework.dao.InvalidDataAccessApiUsageException: No transactional EntityManager available; nested exception is javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410) ~[EntityManagerFactoryUtils.class:4.1.6.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223) ~[HibernateJpaDialect.class:4.1.6.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) ~[AbstractEntityManagerFactoryBean.class:4.1.6.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[ChainedPersistenceExceptionTranslator.class:4.1.6.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[DataAccessUtils.class:4.1.6.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[PersistenceExceptionTranslationInterceptor.class:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [ReflectiveMethodInvocation.class:4.1.6.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122) ~[CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.class:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [ReflectiveMethodInvocation.class:4.1.6.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [ExposeInvocationInterceptor.class:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [ReflectiveMethodInvocation.class:4.1.6.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [JdkDynamicAopProxy.class:4.1.6.RELEASE]
at com.sun.proxy.$Proxy110.deleteByCustomerId(Unknown Source) ~[na:na]

Caused by: javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275) ~[SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.class:4.1.6.RELEASE]
at com.sun.proxy.$Proxy102.remove(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$DeleteExecution.doExecute(JpaQueryExecution.java:270) ~[JpaQueryExecution$DeleteExecution.class:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:74) ~[JpaQueryExecution.class:na]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:97) ~[AbstractJpaQuery.class:na]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:88) ~[AbstractJpaQuery.class:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:395) ~[RepositoryFactorySupport$QueryExecutorMethodInterceptor.class:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373) ~[RepositoryFactorySupport$QueryExecutorMethodInterceptor.class:na]

以下是我的程序结构
配置类

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableTransactionManagement
public class WSApplication {
public static void main(final String[] args) {
SpringApplication.run(WSApplication.class, args);
}
}

@Entity
@Table(Orders)
public class Order {
@id
@GeneratedValue
private long id;

@Column(name = "customerId")
private Long customerId;

// getter & setter methods
// equals & hashCode methods
}

public interface OrderRepository extends JpaRepository<Order, Long> {

List<Order> findByCustomerId(Long customerId);

// 4- @Transactional works fine
void deleteByCustomerId(Long cusotmerId);

}

public class OrderService {

@Autowired
private OrderRepository repo;

// 3- @Transactional works fine
public void deleteOrder(long customerId){
//1- throws exception
repo.deleteByCustomerId(customerId);

//2- following works fine
//repo.delete(repo.findByCustomerId(customerId).get(0));
}

}

在上面的服务类代码中,谁能指导我为什么 2 工作和 1 抛出异常。

谢谢

最佳答案

首先,我引用 Spring-Data JPA Documentation说明为什么 delete 方法适用于您的情况(我的意思是选项 2)。

CRUD methods on repository instances are transactional by default. For reading operations the transaction configuration readOnly flag is set to true, all others are configured with a plain @Transactional so that default transaction configuration applies. For details see JavaDoc of CrudRepository

delete方法其实是CrudRepository的方法。您的存储库扩展了 JpaRepository,它扩展了 CrudRespository,因此它属于 CrudRepository 接口(interface),根据上面的引用是事务性的。

如果您阅读 Transactional Query Method 部分您将看到与选项 4 相同,并且您将知道如何为存储库的所有方法应用自定义事务行为。此外,文档的示例 61 显示了与选项 3 相同的场景。

现在请记住,您不是在使用 JDBC 逻辑,在这种情况下,数据库会处理事务,而是在基于 ORM 的框架内。 ORM 框架需要一个事务来触发对象缓存和数据库之间的同步。因此,您必须了解并为执行 ORM 逻辑的方法(如 deleteByCustomerId)提供事务上下文。

默认情况下 @Transactional(我的意思是没有任何参数)将传播模式设置为 REQUIRED 并将 readOnly 标志设置为 false。当您调用其中注释的方法时,如果不存在,则初始化事务。这就是为什么@LucasSaldanha 的workaround(与示例使用外观为多个存储库调用定义事务 相同)和选项4 的原因强>有效。否则,如果没有事务,您将陷入选项 1 的抛出异常中。

关于java - Spring boot + Hibernate + JPA 没有可用的事务性 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31127309/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com