具有2个数据源的Spring db config-第二个连接抛出HibernateException

时间:2019-04-24 07:35:36

标签: hibernate spring-boot jpa

我正在一个需要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)

0 个答案:

没有答案