繁体   English   中英

Spring 引导数据 Hibernate 事务管理器

[英]Spring Boot Data Hibernate Transaction Manager

我有一个项目(暂时)有两个数据源连接:一个 Neo4j 数据库和一个 PostgreSQL 数据库。 目标是从 Neo4j 迁移到 Postgres,但能够在测试期间来回切换,然后才能永久切换。 两个数据库都配置为使用 spring 引导启动数据。 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)带注释的方法是公共的(它是)并且(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 class 中有一些来自 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);
  }
...
}

暂无
暂无

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

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