【问题标题】:Spring Data - no transaction is in progressSpring Data - 没有正在进行的事务
【发布时间】:2013-12-09 13:09:47
【问题描述】:

我正在尝试配置一个自定义 Spring Data Repository 来替换 spring 的一些功能。

@Repository 接口中一切正常,但在@Repository 实现中,我得到没有事务

错误:

javax.persistence.TransactionRequiredException: no transaction is in progress

这是我的配置文件:

@Configuration
@ComponentScan ({"com.app.core.authentication", "com.app.core.service","com.app.core.repository"})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.app.core.repository"})
public class AppCoreConfiguration implements TransactionManagementConfigurer {

@Bean
public DataSource dataSource()  {
    DataSource dataSource = null;
    try {
        Context ctx = new InitialContext();
        dataSource = (DataSource) ctx.lookup("java:jboss/postgresDS");
    } catch (NamingException e) {
        e.printStackTrace();
    }
    return dataSource;
}

@Bean
public EntityManagerFactory entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);
    vendorAdapter.setShowSql(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.app.core.entity");
    factory.setDataSource(dataSource());
    factory.afterPropertiesSet();

    return factory.getObject();
}

@Bean
public PlatformTransactionManager transactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory());
    txManager.setDataSource(dataSource());
    return txManager;
}


@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator(){
    return new HibernateExceptionTranslator();
}

@Bean
public EntityManager entityManger () {
    return entityManagerFactory().createEntityManager();
}

@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return transactionManager();
}

}

还有我的存储库类:

@Repository
public class ClientRepository extends JPABaseRepository<String, Client> implements IClientRepository {

@Autowired
public ClienteRepository (EntityManager em) {
    super(Cliente.class, em);
}

@Override
@Transactional
public Cliente save(Client client) {
    return saveAndFlush(client);
}
}

还有界面:

@NoRepositoryBean
public interface IClientRepository extends IJPABaseRepository<String, Client> {
    ...
}

有人知道为什么这个自定义的@Repository 类没有获得事务管理器吗? 这很奇怪,因为所有未实现的接口都可以正常工作...

我已经尝试将@Transaction 的注解放在各处...包括从RESOURCE_LOCAL 更改为JTA 等等...

【问题讨论】:

  • 确保你没有复制 bean 实例还有一个问题是你的配置中有一个 EntityManager bean,不要这样做,因为这会创建一个非弹簧托管EntityManager 实例。
  • @M.Deinum 我已经仔细检查了 bean 重复...一切正常。关于EntityManager,我需要在存储库构造函数中注入......唯一的方法是将EntityManager指定为@Bean。有没有办法在不创建明确的EntityManager 的情况下做到这一点?谢谢!
  • 我认为这是一个设计缺陷。 EntityManager 不是线程安全的,应该为每个线程重新创建。通常spring会为你处理这个(它为EntityManager创建一个事务/线程安全代理,它利用了Spring Transaction支持)。您的实例没有。
  • 好吧...我不知道。我将看看解决此问题的替代自定义 Spring 数据存储库。非常感谢您的贡献!
  • JPABaseRepository 类不是来自 Spring Data,至少我不知道那个类,所以它必须是你的库中自定义的东西。一般来说,您应该有一个工厂来实例化您的自定义类,这将负责EntityManager

标签: spring transactions spring-data spring-data-jpa spring-transactions


【解决方案1】:

当使用扩展 Spring Data JPA 的自定义 JPA 存储库时,您需要一个工厂来创建这些存储库的实例。如 Spring Data JPA documentation 中所述。

您当前方法的问题在于您正在创建一个非弹簧管理的EntityManager 实例。

@Bean
public EntityManager entityManger () {
    return entityManagerFactory().createEntityManager();
}

通常 Spring 会为 EntityManager 创建一个 transaction aware proxy,但在您的情况下(由于 @Bean 方法),您的自定义实现会得到一个普通的 EntityManager。创建工厂(如上所述)将解决此问题。

【讨论】:

    猜你喜欢
    • 2015-05-04
    • 2012-02-10
    • 2015-05-11
    • 2016-03-26
    • 2017-12-30
    • 2018-11-11
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多