Конфигурация Spring db с 2 источниками данных - второе соединение выдает HibernateException - PullRequest
0 голосов
/ 24 апреля 2019

Я работаю над проектом Spring, который требует 2 источника данных.Одним из них является сохранение сведений о пользователе, а другим - сохранение информации о продукте и других процессах.

Я определил конфигурацию базы данных следующим образом:

@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 работает хорошо, например, добавление нового продукта с использованием hibernate:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...