我必须在一个项目中使用 JPA 和 Reactive Mongo。最后起作用的是:
- 创建一个
@Configuraition
类来显式创建 JPA 事务管理器,如下所示:
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean dbEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dbDatasource());
em.setPackagesToScan(new String[]{"projectone.mysql"});
em.setPersistenceUnitName("dbEntityManager");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect",env.getProperty("hibernate.dialect"));
properties.put("hibernate.show-sql",env.getProperty("jdbc.show-sql"));
em.setJpaPropertyMap(properties);
return em;
}
@Primary
@Bean
public DataSource dbDatasource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("spring.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
@Primary
@Bean
public PlatformTransactionManager jpaTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
dbEntityManager().getObject());
return transactionManager;
}
}
请注意 bean 名称jpaTransactionManager
,这将是 JPA 中使用的 txManager 名称@Transactional
。
- create
MongoConfiguration
显式创建 Mongo 事务管理器(需要定义很多 bean)
- 在
@Transactional
,用名字称呼他们。默认的transactionManger
将不起作用。你必须区分,喜欢jpaTransactionManager
和reactiveMongoTransactionManger
。
@Transactional(value="jpaTransactionManager")
public void xxx() {
...
}
请注意,JPA 事务方法不能将 Reactor 类型作为返回值(Mono/Flux)。Spring 会强制返回 Mono/Flux 的方法使用 ReactiveTransactionManager,这会造成混乱。