将 Hibernate 连接到两个数据库的问题
Problems with connecting Hibernate to two databases
我在让我的 Java Spring + Hibernate 程序与来自两个不同服务器的两个不同数据库一起工作时遇到问题。
我有两个 DAO-s 和两个用于不同数据库的 DAO 实现文件。
实现文件如下所示:
ErpDao 实现:
@Repository("erpDao")
@Transactional(value="txManager2")
public class ErpDaoImplementation implements ErpDao {
@Autowired
private final SessionFactory sessionFactory2;
@Autowired
public ErpDaoImplementation(@Qualifier(value="sessionFactory2") final SessionFactory sessionFactory2) {
this.sessionFactory2 = sessionFactory2;
}
public Session getSession() {
return sessionFactory2.getCurrentSession();
}
@Override
public ArrayList<ErpOrder> getOrder() {
Criteria criteria = getSession().createCriteria(ErpOrder.class);
return (ArrayList<ErpOrder>) criteria.list();
}
}
PortalDao 实现:
@Repository("portalDao")
@Transactional(value="txManager1")
public class PortalDaoImplementation implements PortalDao {
@Autowired
private final SessionFactory sessionFactory1;
@Autowired
public PortalDaoImplementation(@Qualifier(value="sessionFactory1") final SessionFactory sessionFactory1) {
this.sessionFactory1 = sessionFactory1;
}
public Session getSession() {
return sessionFactory1.getCurrentSession();
}
@Override
public void saveEmployee(NewEmployeeBasic newEmployeeBasic) {
getSession().save(newEmployeeBasic);
}
@SuppressWarnings("unchecked")
@Override
public ArrayList<BasicInfo> findAllEmployees() {
Criteria criteria = getSession().createCriteria(BasicInfo.class).addOrder(Order.asc("name"));
return (ArrayList<BasicInfo>) criteria.list();
}
}
我有两个选项文件,包含关于两个数据库的数据。来自第一个选项文件的任何数据库都可以工作,但其他的则不行。
这也是我的休眠配置文件:
@Configuration
@EnableTransactionManagement
@ComponentScan({"com.alti.hrportal.configuration"})
public class HibernateConfiguration {
private static final PropertiesLoader propertiesLoader1 = new PropertiesLoader();
Properties propHrPortal = propertiesLoader1.load("application.properties");
private static final PropertiesLoader propertiesLoader2 = new PropertiesLoader();
Properties propErp = propertiesLoader2.load("applicationErp.properties");
@Bean
public LocalSessionFactoryBean sessionFactory1() {
LocalSessionFactoryBean sessionFactory1 = new LocalSessionFactoryBean();
sessionFactory1.setDataSource(dataSource1());
sessionFactory1.setPackagesToScan(new String[]{"com.alti.hrportal.model"});
sessionFactory1.setHibernateProperties(hibernateProperties1());
return sessionFactory1;
}
@Bean
@Primary
public LocalSessionFactoryBean sessionFactory2() {
LocalSessionFactoryBean sessionFactory2 = new LocalSessionFactoryBean();
sessionFactory2.setDataSource(dataSource2());
sessionFactory2.setPackagesToScan(new String[]{"com.alti.hrportal.model"});
sessionFactory2.setHibernateProperties(hibernateProperties2());
return sessionFactory2;
}
@Bean
public DataSource dataSource1() {
DriverManagerDataSource dataSource1 = new DriverManagerDataSource();
dataSource1.setDriverClassName(propHrPortal.getProperty("jdbc.driverClassName"));
dataSource1.setUrl(propHrPortal.getProperty("jdbc.url"));
dataSource1.setUsername(propHrPortal.getProperty("jdbc.username"));
dataSource1.setPassword(propHrPortal.getProperty("jdbc.password"));
return dataSource1;
}
@Bean
public DataSource dataSource2() {
DriverManagerDataSource dataSource2 = new DriverManagerDataSource();
dataSource2.setDriverClassName(propErp.getProperty("jdbc.driverClassName"));
dataSource2.setUrl(propErp.getProperty("jdbc.url"));
dataSource2.setUsername(propErp.getProperty("jdbc.username"));
dataSource2.setPassword(propErp.getProperty("jdbc.password"));
return dataSource2;
}
private Properties hibernateProperties1() {
Properties properties1 = new Properties();
properties1.put("hibernate.dialect", propHrPortal.getProperty("hibernate.dialect"));
properties1.put("hibernate.show_sql", propHrPortal.getProperty("hibernate.show_sql"));
properties1.put("hibernate.format_sql", propHrPortal.getProperty("hibernate.format_sql"));
return properties1;
}
private Properties hibernateProperties2() {
Properties properties2 = new Properties();
properties2.put("hibernate.dialect", propErp.getProperty("hibernate.dialect"));
properties2.put("hibernate.show_sql", propErp.getProperty("hibernate.show_sql"));
properties2.put("hibernate.format_sql", propErp.getProperty("hibernate.format_sql"));
return properties2;
}
@Bean
@Autowired
@Qualifier(value = "txManager1")
public HibernateTransactionManager transactionManager1(SessionFactory s) {
HibernateTransactionManager txManager1 = new HibernateTransactionManager();
txManager1.setSessionFactory(s);
return txManager1;
}
@Bean
@Autowired
@Qualifier(value = "txManager2")
public HibernateTransactionManager transactionManager2(SessionFactory s) {
HibernateTransactionManager txManager2 = new HibernateTransactionManager();
txManager2.setSessionFactory(s);
return txManager2;
}
}
我看不出我做错了什么。请帮忙! :)
您的配置和设置在多个方面存在缺陷。首先,字段和构造函数上都有 @Autowired
,它们相互干扰。由于 @Primary
和这些注释,基本上只使用了一个 SessionFactory
。要修复,请从 SessionFactory
字段中删除 @Autowired
。
接下来您需要 2 个 HibernateTransactionManager
而不是一个,每个 SessionFactory
都需要一个,并且您需要在 @Transactional
注释中指定要使用的一个。
@Repository("erpDao")
@Transactional(value="txManager2")
public class ErpDaoImplementation implements ErpDao {
private final SessionFactory sessionFactory2;
@Autowired
public ErpDaoImplementation(@Qualifier(value="sessionFactory2") final SessionFactory sessionFactory2) {
this.sessionFactory2 = sessionFactory2;
}
最后,由于 @Primary
在发生冲突的情况下,将始终使用这个。您想要明确指定使用哪一个。
@Configuration
@EnableTransactionManagement
@ComponentScan({"com.alti.hrportal.configuration"})
public class HibernateConfiguration {
private static final PropertiesLoader propertiesLoader1 = new PropertiesLoader();
Properties propHrPortal = propertiesLoader1.load("application.properties");
private static final PropertiesLoader propertiesLoader2 = new PropertiesLoader();
Properties propErp = propertiesLoader2.load("applicationErp.properties");
@Bean
public LocalSessionFactoryBean sessionFactory2() {
LocalSessionFactoryBean sessionFactory2 = new LocalSessionFactoryBean();
sessionFactory2.setDataSource(dataSource2());
sessionFactory2.setPackagesToScan(new String[]{"com.alti.hrportal.model"});
sessionFactory2.setHibernateProperties(hibernateProperties2());
return sessionFactory2;
}
@Bean(name="txManager1")
public HibernateTransactionManager transactionManager1() {
HibernateTransactionManager txManager1 = new HibernateTransactionManager();
txManager1.setSessionFactory(sessionFactory1().getObject());
return txManager1;
}
@Bean(name="txManager2")
public HibernateTransactionManager transactionManager2() {
HibernateTransactionManager txManager2 = new HibernateTransactionManager();
txManager2.setSessionFactory(sessionFactory2().getObject());
return txManager2;
}
// Omitted other not modified configuration.
}
我在让我的 Java Spring + Hibernate 程序与来自两个不同服务器的两个不同数据库一起工作时遇到问题。
我有两个 DAO-s 和两个用于不同数据库的 DAO 实现文件。 实现文件如下所示:
ErpDao 实现:
@Repository("erpDao")
@Transactional(value="txManager2")
public class ErpDaoImplementation implements ErpDao {
@Autowired
private final SessionFactory sessionFactory2;
@Autowired
public ErpDaoImplementation(@Qualifier(value="sessionFactory2") final SessionFactory sessionFactory2) {
this.sessionFactory2 = sessionFactory2;
}
public Session getSession() {
return sessionFactory2.getCurrentSession();
}
@Override
public ArrayList<ErpOrder> getOrder() {
Criteria criteria = getSession().createCriteria(ErpOrder.class);
return (ArrayList<ErpOrder>) criteria.list();
}
}
PortalDao 实现:
@Repository("portalDao")
@Transactional(value="txManager1")
public class PortalDaoImplementation implements PortalDao {
@Autowired
private final SessionFactory sessionFactory1;
@Autowired
public PortalDaoImplementation(@Qualifier(value="sessionFactory1") final SessionFactory sessionFactory1) {
this.sessionFactory1 = sessionFactory1;
}
public Session getSession() {
return sessionFactory1.getCurrentSession();
}
@Override
public void saveEmployee(NewEmployeeBasic newEmployeeBasic) {
getSession().save(newEmployeeBasic);
}
@SuppressWarnings("unchecked")
@Override
public ArrayList<BasicInfo> findAllEmployees() {
Criteria criteria = getSession().createCriteria(BasicInfo.class).addOrder(Order.asc("name"));
return (ArrayList<BasicInfo>) criteria.list();
}
}
我有两个选项文件,包含关于两个数据库的数据。来自第一个选项文件的任何数据库都可以工作,但其他的则不行。
这也是我的休眠配置文件:
@Configuration
@EnableTransactionManagement
@ComponentScan({"com.alti.hrportal.configuration"})
public class HibernateConfiguration {
private static final PropertiesLoader propertiesLoader1 = new PropertiesLoader();
Properties propHrPortal = propertiesLoader1.load("application.properties");
private static final PropertiesLoader propertiesLoader2 = new PropertiesLoader();
Properties propErp = propertiesLoader2.load("applicationErp.properties");
@Bean
public LocalSessionFactoryBean sessionFactory1() {
LocalSessionFactoryBean sessionFactory1 = new LocalSessionFactoryBean();
sessionFactory1.setDataSource(dataSource1());
sessionFactory1.setPackagesToScan(new String[]{"com.alti.hrportal.model"});
sessionFactory1.setHibernateProperties(hibernateProperties1());
return sessionFactory1;
}
@Bean
@Primary
public LocalSessionFactoryBean sessionFactory2() {
LocalSessionFactoryBean sessionFactory2 = new LocalSessionFactoryBean();
sessionFactory2.setDataSource(dataSource2());
sessionFactory2.setPackagesToScan(new String[]{"com.alti.hrportal.model"});
sessionFactory2.setHibernateProperties(hibernateProperties2());
return sessionFactory2;
}
@Bean
public DataSource dataSource1() {
DriverManagerDataSource dataSource1 = new DriverManagerDataSource();
dataSource1.setDriverClassName(propHrPortal.getProperty("jdbc.driverClassName"));
dataSource1.setUrl(propHrPortal.getProperty("jdbc.url"));
dataSource1.setUsername(propHrPortal.getProperty("jdbc.username"));
dataSource1.setPassword(propHrPortal.getProperty("jdbc.password"));
return dataSource1;
}
@Bean
public DataSource dataSource2() {
DriverManagerDataSource dataSource2 = new DriverManagerDataSource();
dataSource2.setDriverClassName(propErp.getProperty("jdbc.driverClassName"));
dataSource2.setUrl(propErp.getProperty("jdbc.url"));
dataSource2.setUsername(propErp.getProperty("jdbc.username"));
dataSource2.setPassword(propErp.getProperty("jdbc.password"));
return dataSource2;
}
private Properties hibernateProperties1() {
Properties properties1 = new Properties();
properties1.put("hibernate.dialect", propHrPortal.getProperty("hibernate.dialect"));
properties1.put("hibernate.show_sql", propHrPortal.getProperty("hibernate.show_sql"));
properties1.put("hibernate.format_sql", propHrPortal.getProperty("hibernate.format_sql"));
return properties1;
}
private Properties hibernateProperties2() {
Properties properties2 = new Properties();
properties2.put("hibernate.dialect", propErp.getProperty("hibernate.dialect"));
properties2.put("hibernate.show_sql", propErp.getProperty("hibernate.show_sql"));
properties2.put("hibernate.format_sql", propErp.getProperty("hibernate.format_sql"));
return properties2;
}
@Bean
@Autowired
@Qualifier(value = "txManager1")
public HibernateTransactionManager transactionManager1(SessionFactory s) {
HibernateTransactionManager txManager1 = new HibernateTransactionManager();
txManager1.setSessionFactory(s);
return txManager1;
}
@Bean
@Autowired
@Qualifier(value = "txManager2")
public HibernateTransactionManager transactionManager2(SessionFactory s) {
HibernateTransactionManager txManager2 = new HibernateTransactionManager();
txManager2.setSessionFactory(s);
return txManager2;
}
}
我看不出我做错了什么。请帮忙! :)
您的配置和设置在多个方面存在缺陷。首先,字段和构造函数上都有 @Autowired
,它们相互干扰。由于 @Primary
和这些注释,基本上只使用了一个 SessionFactory
。要修复,请从 SessionFactory
字段中删除 @Autowired
。
接下来您需要 2 个 HibernateTransactionManager
而不是一个,每个 SessionFactory
都需要一个,并且您需要在 @Transactional
注释中指定要使用的一个。
@Repository("erpDao")
@Transactional(value="txManager2")
public class ErpDaoImplementation implements ErpDao {
private final SessionFactory sessionFactory2;
@Autowired
public ErpDaoImplementation(@Qualifier(value="sessionFactory2") final SessionFactory sessionFactory2) {
this.sessionFactory2 = sessionFactory2;
}
最后,由于 @Primary
在发生冲突的情况下,将始终使用这个。您想要明确指定使用哪一个。
@Configuration
@EnableTransactionManagement
@ComponentScan({"com.alti.hrportal.configuration"})
public class HibernateConfiguration {
private static final PropertiesLoader propertiesLoader1 = new PropertiesLoader();
Properties propHrPortal = propertiesLoader1.load("application.properties");
private static final PropertiesLoader propertiesLoader2 = new PropertiesLoader();
Properties propErp = propertiesLoader2.load("applicationErp.properties");
@Bean
public LocalSessionFactoryBean sessionFactory2() {
LocalSessionFactoryBean sessionFactory2 = new LocalSessionFactoryBean();
sessionFactory2.setDataSource(dataSource2());
sessionFactory2.setPackagesToScan(new String[]{"com.alti.hrportal.model"});
sessionFactory2.setHibernateProperties(hibernateProperties2());
return sessionFactory2;
}
@Bean(name="txManager1")
public HibernateTransactionManager transactionManager1() {
HibernateTransactionManager txManager1 = new HibernateTransactionManager();
txManager1.setSessionFactory(sessionFactory1().getObject());
return txManager1;
}
@Bean(name="txManager2")
public HibernateTransactionManager transactionManager2() {
HibernateTransactionManager txManager2 = new HibernateTransactionManager();
txManager2.setSessionFactory(sessionFactory2().getObject());
return txManager2;
}
// Omitted other not modified configuration.
}