简体   繁体   English

Spring 引导数据 Hibernate 事务管理器

[英]Spring Boot Data Hibernate Transaction Manager

I have a project which (temporarily) has two data sources wired up: a Neo4j database and a PostgreSQL database.我有一个项目(暂时)有两个数据源连接:一个 Neo4j 数据库和一个 PostgreSQL 数据库。 The goal is to migrate from Neo4j to Postgres, but be able to switch back and forth during testing before making the switch permanent.目标是从 Neo4j 迁移到 Postgres,但能够在测试期间来回切换,然后才能永久切换。 Both databases are configured to use spring boot starter data.两个数据库都配置为使用 spring 引导启动数据。 Neo4j works great, and has for a while, but I'm having difficulty getting transaction management to work with Postgres. Neo4j 效果很好,并且有一段时间,但我很难让事务管理与 Postgres 一起工作。

I am using Spring Boot 1.5.3, which I know is old, but upgrading it at this point is not an option.我正在使用 Spring Boot 1.5.3,我知道它很旧,但此时升级它不是一个选项。

The dependencies in the pom.xml file look like (along with driver dependencies, etc) pom.xml 文件中的依赖项看起来像(以及驱动程序依赖项等)

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-neo4j</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>2.7.8</version>
      <scope>compile</scope>
    </dependency>

I also have Flyway hooked up and running properly against the Postgres database.我还连接了 Flyway 并针对 Postgres 数据库正常运行。

Initially, I was using a DataSourceTransactionManager for transaction management, but I was getting the following error when hitting a method annotated with @Transactional(transactionManager = "transactionManager") (see configuration below for why I needed the transactionManager property)最初,我使用DataSourceTransactionManager进行事务管理,但在点击使用@Transactional(transactionManager = "transactionManager")注释的方法时出现以下错误(请参阅下面的配置了解为什么我需要transactionManager属性)

org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress;
nested exception is javax.persistence.TransactionRequiredException: no transaction is in
progress

Most answers/tips about that particular error tell me that @Transactional requires that (a) the annotated method is public (it is) and (b) it must be called from outside the bean (it is)--here's the relevant code:关于该特定错误的大多数答案/提示告诉我@Transactional要求(a)带注释的方法是公共的(它是)并且(b)它必须从 bean 外部调用(它是)-这是相关代码:

@Component
public class MyEntityDao {

  @Autowired
  private MyEntityRepositoryHelper repositoryHelper;

  public save(MyEntity entity) {
    repositoryHelper.saveEntity(entity)
  }
} 

and

@Component
public class MyEntityRepositoryHelper {

  @Autowired
  private MyEntityRepository repository;

  @Transactional(transactionManager = "transactionManager")
  public MyEntity saveMyEntity(MyEntity entity) {
    MyEntity saved = repository.saveAndFlush(entity);
    ... // do stuff with saved entity
    saved = repository.saveAndFlush(entity);
    ... // do more stuff with saved entity
    return saved;
  }
...
}

and the repository:和存储库:

public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
...
}

After much searching, I found that I needed a HibernateTransactionManager , so I set about configuring one.经过大量搜索,我发现我需要一个HibernateTransactionManager ,所以我开始配置一个。 Many hours and lots of research later, I have arrived at the following configuration (the data source is properly autoconfigured):经过数小时和大量研究后,我得出了以下配置(数据源已正确自动配置):

@Configuration
@EnableAsync
@EnableTransactionManagement
@PropertySources( {
    @PropertySource(value = "classpath:application.properties",
        ignoreResourceNotFound = false)
})
public class ApplicationConfig {
  @Autowired
  private Neo4jTransactionManager neo4jTransactionManager;

  @Autowired
  private HikariDataSource dataSource;

  @Bean
  public Neo4jTransactionManager neo4jTransactionManager() {
    return neo4jTransactionManager;
  }

  @Bean
  public SessionFactory postgresSessionFactory() {
    return new LocalSessionFactoryBuilder(dataSource)
        .addPackages("path.to.the.data.postgresql.model")
        .buildSessionFactory();
  }

  @Bean
  public PlatformTransactionManager transactionManager() {
    return new HibernateTransactionManager(postgresSessionFactory());
  }
...
}

Now I'm getting this error:现在我收到此错误:

org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate
Session for transaction; nested exception is java.lang.NoClassDefFoundError: org/hibernate
/engine/transaction/spi/TransactionContext

I have spent hours already on this and I really need to start moving forward.我已经为此花费了几个小时,我真的需要开始前进。 Any ideas?有任何想法吗?

Edit: I realized that Hibernate 5 is being used and I had some imports from Hibernate 4 in the ApplicationConfig class.编辑:我意识到正在使用 Hibernate 5 并且我在 ApplicationConfig class 中有一些来自 Hibernate 4 的导入。 I switched those to Hibernate 5 and I'm back to the "no transaction is in progress" error.我将它们切换到 Hibernate 5 并且我回到了“没有事务正在进行中”错误。

org.springframework.dao.InvalidDataAccessApiUsageException: no transaction
is in progress; nested exception is
javax.persistence.TransactionRequiredException: no transaction is in
progress

It appears that I was misinformed when told that I needed a HibernateTransactionManager .当被告知我需要一个HibernateTransactionManager时,我似乎被误导了。 What I really needed was a JpaTransactionManager .我真正需要的是JpaTransactionManager I changed ApplicationConfig to the following and it worked.我将 ApplicationConfig 更改为以下内容并且它有效。

@Configuration
@EnableAsync
@EnableTransactionManagement
@PropertySources( {
    @PropertySource(value = "classpath:application.properties",
        ignoreResourceNotFound = false)
})
public class ApplicationConfig {

  @Autowired
  private Neo4jTransactionManager neo4jTransactionManager;

  @Bean
  public Neo4jTransactionManager neo4jTransactionManager() {
    return neo4jTransactionManager;
  }

  @Bean
  public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    return new JpaTransactionManager(entityManagerFactory);
  }
...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM