【问题标题】:JpaRepository: No Transaction in progressJpaRepository:没有正在进行的事务
【发布时间】:2014-08-19 18:59:47
【问题描述】:

我正在使用 Spring Data Jpa 和 hibernate。我有一个扩展 JpaRepository 的存储库,我正在使用它将记录保存到数据库中。但是当我调用 .flush() 时,出现以下错误。

我看到其他问题有类似的错误,但在存储库中也尝试使用 @Transaction 后,我得到了同样的错误。

Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
    at com.sun.proxy.$Proxy64.flush(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:262)
    at com.sun.proxy.$Proxy64.flush(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.flush(SimpleJpaRepository.java:397)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:365)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 75 more

存储库

@Repository
@Transactional
public interface AttributeRepository extends JpaRepository<Attribute, Long> {
    Attribute findById(long id);
}

我的配置包含 JPA 需要的实体管理器工厂和平台事务管理器,

@Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(BoneCPDataSource ds) throws IOException {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(ds);
        em.setPackagesToScan(new String[] { "org.scripps.branch.entity" });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        return em;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Bean
    public PlatformTransactionManager transactionManager(
            EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

调用saveandFlush()方法的Service,

@Service
public interface FeatureService {

    @Transactional
    public List<Feature> rankFeatures(Instances data, List<String> entrezIds, Dataset d);
}

补充一下,我将使用 @Autowired 的存储库注入到服务的实现中。

【问题讨论】:

  • 是的,我有注释。我可以使用存储库检索对象,但无法保存和刷新实体。

标签: spring hibernate spring-data-jpa


【解决方案1】:

我认为您忘记启用 Jpa Transaction 或将 Spring Data 与事务管理器关联:

Ex 启用事务管理:

@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)

Jpa 存储库的前助理事务经理:

@EnableJpaRepositories(transactionManagerRef="transactionManager", 
    entityManagerFactoryRef="entityManagerFactory", 
    value="com.repositories.pkg.location" )

【讨论】:

  • 我在我的配置中同时使用了@EnableTransactionManagement@EnableJpaRepositories(basePackages = { "org.scripps.branch.repository" })。注意:仓库可以查询数据,只有在我使用flush()时才会报错
  • 您使用的是上面提到的 AspectJ 方法还是基于代理的方法?尝试后者,因为它设置起来更简单。
  • 错误消息显示“没有正在进行的事务”,所以我认为这可能是配置中的问题。也许 Hille 是对的,可能与您的交易模式 Aspect 或代理有关。你正在使用女巫吗?
【解决方案2】:

使用@Transactional 注释您的存储库将无济于事;您必须使用@Transactional 注释服务方法。 “服务方法”表示封装这两者的方法,对 repo 的 save 方法的调用和 flush 调用。

【讨论】:

  • 我已将@Transactional 添加到服务方法中,但仍然出现相同的错误。我正在为该服务使用一个接口,并且我已经在接口中注释了该方法,并使用@Transactional 对其实现进行了注释。
  • 作为旁注,引用弹簧参考:Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. 两次注释不会造成任何伤害,但可能会造成混淆。
  • 哦,不。你误会了:-)。针对服务接口进行编程是一种很好的做法;所以保留你的接口和实现。只是不要注释两次(接口+实现),而是一次(实现)。
  • 啊,好吧。我明白。谢谢!
【解决方案3】:

我解决了。我的配置文件分为 2 类,一类用于应用程序上下文,另一类用于持久性上下文。我将它们结合起来,错误消失了。

【讨论】:

  • 不完全确定为什么。
  • 奇怪。您的任何配置类是否已声明为 final 或没有无参数构造函数?很高兴听到它至少有效。
猜你喜欢
  • 2013-03-23
  • 2014-04-25
  • 2012-07-29
  • 2013-02-22
  • 2019-06-28
  • 1970-01-01
  • 2015-05-11
  • 2016-03-26
  • 2013-12-09
相关资源
最近更新 更多