我们的应用程序需要处理多个数据库。 我们尝试通过Hibernate配置配置多个数据源,并为数据库1添加了两个配置,为数据库2添加了第二个配置。此配置因以下异常而失败
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'dataDAO'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataDAO': Unsatisfied dependency expressed through field 'sessionFactory'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.hibernate.SessionFactory' available: expected single matching bean but found 2: sessionFactory1,sessionFactory2 Nov 29, 2019 5:08:11 PM org.springframework.web.context.ContextLoader initWebApplicationContext SEVERE: Context initialization failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'dataDAO'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataDAO': Unsatisfied dependency expressed through field 'sessionFactory'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.hibernate.SessionFactory' available: expected single matching bean but found 2: sessionFactory1,sessionFactory2 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
这是我的Configuration类:
package com.pack1.config; import java.beans.PropertyVetoException; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.logging.Logger; import javax.sql.DataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySources; import org.springframework.core.env.Environment; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.pack1.routing.MyRoutingDataSource; @Configuration @ComponentScan("com.pack1") @EnableWebMvc @EnableTransactionManagement // Load to Environment @PropertySources({@PropertySource("classpath:ds/datasource-cfg.properties")}) public class ApplicationContextConfig implements WebMvcConfigurer { // The Environment class serves as the property holder // and stores all the properties loaded by the @PropertySource @Autowired private Environment env; private Logger logger = Logger.getLogger(getClass().getName()); @Bean(name = "viewResolver") public InternalResourceViewResolver getViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/pages/"); viewResolver.setSuffix(".jsp"); return viewResolver; } // Returns Routing DataSource (MyRoutingDataSource) @Autowired @Bean(name = "dataSource") public DataSource getDataSource(DataSource dataSource1, DataSource dataSource2) { System.out.println("## Create DataSource from dataSource1 & dataSource2"); MyRoutingDataSource dataSource = new MyRoutingDataSource(); Map<Object, Object> dsMap = new HashMap<Object, Object>(); dsMap.put("PUBLISHER_DS", dataSource1); dsMap.put("ADVERTISER_DS", dataSource2); dataSource.setTargetDataSources(dsMap); return dataSource; } @Bean(name = "dataSource1") public DataSource getDataSource1() throws SQLException, PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); // See: datasouce-cfg.properties dataSource.setDriverClass(env.getProperty("ds.database-driver1")); dataSource.setJdbcUrl(env.getProperty("ds.url1")); dataSource.setUser(env.getProperty("ds.username1")); dataSource.setPassword(env.getProperty("ds.password1")); System.out.println("## getDataSource1: " + dataSource); return dataSource; } private Properties getHibernateProperties1() { // set hibernate properties Properties props = new Properties(); props.setProperty("ds.hibernate.dialect1", env.getProperty("ds.hibernate.dialect1")); props.setProperty("ds.hibernate.show_sql1", env.getProperty("ds.hibernate.show_sql1")); return props; } // need a helper method // read environment property and convert to int private int getIntProperty1(String propName) { String propVal = env.getProperty(propName); // now convert to int int intPropVal = Integer.parseInt(propVal); return intPropVal; } @Bean public LocalSessionFactoryBean sessionFactory1() throws SQLException, PropertyVetoException{ // create session factorys LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); // set the properties sessionFactory.setDataSource(getDataSource1()); sessionFactory.setPackagesToScan(env.getProperty("ds.hibernate.packagesToScan1")); sessionFactory.setHibernateProperties(getHibernateProperties1()); return sessionFactory; } @Autowired @Bean(name = "transactionManager") public HibernateTransactionManager getTransactionManager1(SessionFactory sessionFactory1) { // setup transaction manager based on session factory HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory1); return txManager; } @Bean(name = "dataSource2") public DataSource getDataSource2() throws SQLException, PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); // See: datasouce-cfg.properties dataSource.setDriverClass(env.getProperty("ds.database-driver2")); dataSource.setJdbcUrl(env.getProperty("ds.url2")); dataSource.setUser(env.getProperty("ds.username2")); dataSource.setPassword(env.getProperty("ds.password2")); System.out.println("## getDataSource2: " + dataSource); return dataSource; } private Properties getHibernateProperties2() { // set hibernate properties Properties props = new Properties(); props.setProperty("ds.hibernate.dialect2", env.getProperty("ds.hibernate.dialect2")); props.setProperty("ds.hibernate.show_sql2", env.getProperty("ds.hibernate.show_sql2")); return props; } // need a helper method // read environment property and convert to int private int getIntProperty2(String propName) { String propVal = env.getProperty(propName); // now convert to int int intPropVal = Integer.parseInt(propVal); return intPropVal; } @Bean public LocalSessionFactoryBean sessionFactory2() throws SQLException, PropertyVetoException{ // create session factorys LocalSessionFactoryBean sessionFactory1 = new LocalSessionFactoryBean(); // set the properties sessionFactory1.setDataSource(getDataSource2()); sessionFactory1.setPackagesToScan(env.getProperty("ds.hibernate.packagesToScan2")); sessionFactory1.setHibernateProperties(getHibernateProperties2()); return sessionFactory1; } @Autowired @Bean(name = "transactionManager") public HibernateTransactionManager getTransactionManage2(SessionFactory sessionFactory1) { // setup transaction manager based on session factory HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory1); return txManager; } }
我是在Spring MVC中使用多个数据源的新手。 请帮我编码在Hibernate Configuration类中。