我有一个项目,它(暂时(连接了两个数据源: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(带注释的方法是公共的(它是(,(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);
}
...
}