我有一个项目(暂时)连接了两个数据源:一个 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/