我正在一个需要2个数据源的Spring项目中。一种是保存用户详细信息,另一种是保存产品信息和其他过程。
我将数据库配置定义如下:
@Value("${caffein.datasource.url}")
private String APP_DB_URL;
@Value("${caffein.datasource.driver-class-name}")
private String APP_DRIVER_CLASS_NAME;
@Value("${caffein.datasource.package.to.scan}")
private String PACKAGE_TO_SCAN;
@Value("${caffein.users.datasource.url}")
private String USERS_DB_URL;
@Value("${caffein.datasource.driver-class-name}")
private String USERS_DRIVER_CLASS_NAME;
@Value("${caffein.datasource.username}")
private String USERNAME;
@Value("${caffein.datasource.password}")
private String PASSWORD;
@Value(value = "caffein.hibernate.dialect")
private String HIBERNATE_DIALECT;
@Value("${caffein.hibernate.showSQL}")
private String HIBERNATE_SHOW_SQL;
@Bean
@Primary
@ConfigurationProperties("caffein.datasource")
public DataSourceProperties appDataSourceProperties() {
System.out.println("db url: " + APP_DB_URL);
logger.info("========Config App Database========");
DataSourceProperties properties = new DataSourceProperties();
properties.setDriverClassName(APP_DRIVER_CLASS_NAME);
properties.setUrl(APP_DB_URL);
properties.setUsername(USERNAME);
properties.setPassword(PASSWORD);
logger.info("DB url: " + env.getProperty(properties.determineUrl()));
return properties;
}
public Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
hibernateProperties.setProperty("hibernate.show_sql", HIBERNATE_SHOW_SQL);
return hibernateProperties;
}
@Bean
@Primary
@ConfigurationProperties("caffein.datasource.configuration")
public BasicDataSource appDataSource() {
return appDataSourceProperties().initializeDataSourceBuilder().type(BasicDataSource.class).build();
}
@Bean
@Primary
@Qualifier("appSessionFactory")
public LocalSessionFactoryBean appSessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(this.appDataSource());
sessionFactory.setPackagesToScan(PACKAGE_TO_SCAN);
sessionFactory.setHibernateProperties(this.hibernateProperties());
return sessionFactory;
}
@Bean
@ConfigurationProperties("caffein.users.datasource")
public DataSourceProperties usersDataSourceProperties() {
logger.info("========Users Database========");
DataSourceProperties properties = new DataSourceProperties();
properties.setDriverClassName(USERS_DRIVER_CLASS_NAME);
properties.setUrl(USERS_DB_URL);
properties.setUsername(USERNAME);
properties.setPassword(PASSWORD);
logger.info("DB url: " + env.getProperty(properties.determineUrl()));
return properties;
}
@Bean
@ConfigurationProperties("caffein.users.datasource.configuration")
public BasicDataSource usersDataSource() {
return usersDataSourceProperties().initializeDataSourceBuilder().type(BasicDataSource.class).build();
}
@Bean
@Qualifier("usersSessionFactory")
public LocalSessionFactoryBean usersSessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(this.usersDataSource());
sessionFactory.setPackagesToScan(PACKAGE_TO_SCAN);
sessionFactory.setHibernateProperties(this.hibernateProperties());
return sessionFactory;
}
为数据库定义配置后,类AbstractDAO包含2个在配置中创建的会话:
public class AbstractDAO {
@Autowired
@Qualifier("appSessionFactory")
protected SessionFactory appSessionFactory;
@Autowired
@Qualifier("usersSessionFactory")
protected SessionFactory usersSessionFactory;
}
第一个appSessionFactory
会话工厂运行良好,例如使用休眠模式添加新产品:
public void saveProduct(Product entity) {
this.appSessionFactory.getCurrentSession().save(entity);
}
但是我无法使用相同的方式保存新用户:
public void addNewUser(User entity) {
this.usersSessionFactory.getCurrentSession().save(entity);
}
那么代码中有什么问题?
这是我的类UserDAO:
@Repository
public class UserDAO extends AbstractDAO {
public User findByUsername(String username) {
CriteriaBuilder builder = this.usersSessionFactory.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.where(builder.equal(root.get("username"), username));
return this.usersSessionFactory.createEntityManager().createQuery(criteria).getSingleResult();
}
public void addNewUser(User entity) {
this.usersSessionFactory.getCurrentSession().save(entity);
}
}
例外是:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:143)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:497)
at the.caffein.dao.UserDAO.addNewUser(UserDAO.java:23)
at the.caffein.dao.UserDAO$$FastClassBySpringCGLIB$$e1b2174c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)