java - Spring Boot 数据 Hibernate 事务管理器

标签 java spring-boot hibernate spring-data-jpa

我有一个项目(暂时)连接了两个数据源:一个 Neo4j 数据库和一个 PostgreSQL 数据库。目标是从 Neo4j 迁移到 Postgres,但能够在测试期间来回切换,然后才能永久切换。两个数据库都配置为使用 spring boot starter 数据。 Neo4j 工作得很好,而且已经有一段时间了,但我很难让事务管理与 Postgres 一起工作。

我使用的是 Spring Boot 1.5.3,我知道它很旧,但此时升级它不是一个选择。

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>

我还连接了 Flyway,并针对 Postgres 数据库正确运行。

最初,我使用 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

关于该特定错误的大多数答案/提示告诉我,@Transactional 要求 (a) 带注释的方法是公共(public)的(它是)并且 (b) 必须从 bean 外部调用它(是的)--这是相关代码:

@Component
public class MyEntityDao {

  @Autowired
  private MyEntityRepositoryHelper repositoryHelper;

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

@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;
  }
...
}

和存储库:

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

经过一番搜索,我发现我需要一个 HibernateTransactionManager,所以我开始配置一个。经过许多小时和大量研究后,我得到了以下配置(数据源已正确自动配置):

@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());
  }
...
}

现在我收到此错误:

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

我已经花了几个小时在这上面,我真的需要开始前进。有什么想法吗?

编辑: 我意识到正在使用 Hibernate 5,并且我在 ApplicationConfig 类中从 Hibernate 4 导入了一些内容。我将它们切换到 Hibernate 5,然后又回到“没有事务正在进行中”错误。

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

最佳答案

当我被告知我需要一个 HibernateTransactionManager 时,我似乎被误导了。我真正需要的是一个JpaTransactionManager。我将 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);
  }
...
}

关于java - Spring Boot 数据 Hibernate 事务管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63138776/

相关文章:

spring-boot - Spring Boot Autowiring 失败 - null

java - 调用具有 Autowiring 值的方法

java - 如何在 web View 中单击 div 时完成 Activity

spring - spring boot 上 thymeleaf 的多个模板解析器

java - 尝试使用 hibernate 连接 mysql 时连接被拒绝

java - UUID 在 Java Hibernate 和 SQL Server 中的不同表示

java - 为什么在使用@JoinTable 时会忽略@DiscriminatorColumn?

java - 为什么我的 Java 程序只在文件中添加一半的数字列表?

java - Android Studio 突然在 Logcat 中显示太多日志

java - 匹配整个 Java 异常堆栈跟踪的正则表达式