我需要从单个应用程序连接到两个不同的数据库。问题是我的appEntityManager没有与之关联的事务管理器,我不知道该怎么做。 @Primary adminEntityManager能够使用spring boot提供的那个,没有任何问题,如here所述。
上面的配置几乎可以单独使用。完成了 你需要为这两个配置TransactionManagers的图片 EntityManagers也是如此。其中一个可以默认选中 如果你将它标记为@Primary,则在Spring Boot中使用JpaTransactionManager。该 其他必须明确地注入新实例。或者您 也许可以使用跨越两者的JTA事务管理器。
我已使用
注释了配置@EnableTransactionManagement
这是相关豆
@Bean
@ConfigurationProperties(prefix = "datasource.app")
public DataSource appDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.admin")
public DataSource adminDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public LocalContainerEntityManagerFactoryBean appEntityManagerFactory(
final EntityManagerFactoryBuilder builder) {
return builder
.dataSource(appDataSource())
.packages("au.com.mycompany.app.bomcommon.domain")
.persistenceUnit("appPersistentUnit")
.build();
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean adminEntityManagerFactory(
final EntityManagerFactoryBuilder builder) {
return builder
.dataSource(adminDataSource())
.packages("au.com.mycompany.app.bombatch")
.persistenceUnit("adminPersistentUnit")
.build();
}
//I thought this would do it but I am getting an exception
//No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: appTransactionManager,transactionManager
@Bean
public JpaTransactionManager appTransactionManager(@Qualifier("appEntityManagerFactory") final EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
我最后以不同的方式做到了。 see here
答案 0 :(得分:4)
看看是否有效:
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.admin")
public DataSource adminDS() { ... }
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean adminEMF(...) { ... }
@Bean
@Primary
public JpaTransactionManager adminTM(...) { ... }
@Bean
public LocalContainerEntityManagerFactoryBean appEMF(...) { ... }
@Bean
public JpaTransactionManager appTM(...) { ... }
我对您的配置进行的唯一更改是明确声明管理员端的事务管理器,并将该事务管理器标记为默认值。
答案 1 :(得分:0)
请参阅以下更改。这个对我有用。创建了3个数据源,3个会话工厂和3个事务管理器。如下将这些事务管理器添加到chainedTransaction中:
@Configuration
@EnableTransactionManagement
public class HibernateConfiguration implements TransactionManagementConfigurer {
@Bean("chainedTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("transactionManager1") final HibernateTransactionManager transactionManager1,
@Qualifier("transactionManager2") final HibernateTransactionManager transactionManager2,
@Qualifier("transactionManager3") final HibernateTransactionManager transactionManager3) {
return new ChainedTransactionManager(transactionManager1, transactionManager2, transactionManager3);
}
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
// TODO Auto-generated method stub
return transactionManager(oneTransactionManager(), twoTransactionManager(), threeTransactionManager());
}
@Bean(name = "oneDataSource", destroyMethod="")
public DataSource oneDataSource() throws IllegalArgumentException, NamingException, SQLException {
HikariConfig hkConfig = new HikariConfig();
System.out.println(env.getRequiredProperty("spring1-datasource.jdbcUrl"));
hkConfig.setJdbcUrl(env.getRequiredProperty("spring1-datasource.jdbcUrl"));
hkConfig.setUsername(env.getRequiredProperty("spring1-datasource.username"));
hkConfig.setPassword(env.getRequiredProperty("spring1-datasource.password"));
hkConfig.setDriverClassName(env.getRequiredProperty("spring1-datasource.driverClassName"));
return new HikariDataSource(hkConfig);
}
@Bean(name="oneSessionFactory")
@Qualifier("oneSessionFactory")
public LocalSessionFactoryBean oneSessionFactory() throws IllegalArgumentException, NamingException, SQLException {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(oneDataSource());
sessionFactory.setPackagesToScan(env.getRequiredProperty("entitymanager.packagesToScan"));
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
hibernateProperties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
sessionFactory.setHibernateProperties(hibernateProperties);
return sessionFactory;
}
@Bean(name="transactionManager1")
public HibernateTransactionManager oneTransactionManager() {
HibernateTransactionManager oneTransactionManager = new HibernateTransactionManager();
try {
oneTransactionManager.setSessionFactory(oneSessionFactory().getObject());
} catch (IllegalArgumentException | NamingException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return oneTransactionManager
}
@Bean(name = "twoDataSource", destroyMethod="")
public DataSource twoDataSource() throws IllegalArgumentException, NamingException, SQLException {
HikariConfig hkConfig = new HikariConfig();
System.out.println(env.getRequiredProperty("spring2-datasource.jdbcUrl"));
hkConfig.setJdbcUrl(env.getRequiredProperty("spring2-datasource.jdbcUrl"));
hkConfig.setUsername(env.getRequiredProperty("spring2-datasource.username"));
hkConfig.setPassword(env.getRequiredProperty("spring2-datasource.password"));
hkConfig.setDriverClassName(env.getRequiredProperty("spring2-datasource.driverClassName"));
return new HikariDataSource(hkConfig);
}
@Bean(name="twoSessionFactory")
@Qualifier("twoSessionFactory")
public LocalSessionFactoryBean twoSessionFactory() throws IllegalArgumentException, NamingException, SQLException {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(twoDataSource());
sessionFactory.setPackagesToScan(env.getRequiredProperty("entitymanager.packagesToScan"));
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
hibernateProperties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
sessionFactory.setHibernateProperties(hibernateProperties);
return sessionFactory;
}
@Bean(name="transactionManager2")
public HibernateTransactionManager twoTransactionManager() {
HibernateTransactionManager twoTransactionManager = new HibernateTransactionManager();
try {
twoTransactionManager.setSessionFactory(twoSessionFactory().getObject());
} catch (IllegalArgumentException | NamingException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return twoTransactionManager
}
@Bean(name = "threeDataSource", destroyMethod="")
public DataSource threeDataSource() throws IllegalArgumentException, NamingException, SQLException {
HikariConfig hkConfig = new HikariConfig();
System.out.println(env.getRequiredProperty("spring3-datasource.jdbcUrl"));
hkConfig.setJdbcUrl(env.getRequiredProperty("spring3-datasource.jdbcUrl"));
hkConfig.setUsername(env.getRequiredProperty("spring3-datasource.username"));
hkConfig.setPassword(env.getRequiredProperty("spring3-datasource.password"));
hkConfig.setDriverClassName(env.getRequiredProperty("spring3-datasource.driverClassName"));
return new HikariDataSource(hkConfig);
}
@Bean(name="threeSessionFactory")
@Qualifier("threeSessionFactory")
public LocalSessionFactoryBean threeSessionFactory() throws IllegalArgumentException, NamingException, SQLException {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(threeDataSource());
sessionFactory.setPackagesToScan(env.getRequiredProperty("entitymanager.packagesToScan"));
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
hibernateProperties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
sessionFactory.setHibernateProperties(hibernateProperties);
return sessionFactory;
}
@Bean(name="transactionManager3")
public HibernateTransactionManager threeTransactionManager() {
HibernateTransactionManager threeTransactionManager = new HibernateTransactionManager();
try {
threeTransactionManager.setSessionFactory(threeSessionFactory().getObject());
} catch (IllegalArgumentException | NamingException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return threeTransactionManager
}
}