当前位置: 首页 > 知识库问答 >
问题:

带有Hibernate的Spring多重数据源给出:未找到会话错误

吴弘壮
2023-03-14

我正在将Spring 4与Hibernate 4一起使用,并尝试配置多个数据源。当我使用新的第二个时,我总是收到错误。

    package org.miso.vre.config;

import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

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.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@ComponentScan("org.miso.vre")
@PropertySource("classpath:database.properties")
public class DatabaseConfig {

    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";

    private static final String PROPERTY_NAME_DATABASE_MISOFT_DRIVER = "db.misoft.driver";
    private static final String PROPERTY_NAME_DATABASE_MISOFT_PASSWORD = "db.misoft.password";
    private static final String PROPERTY_NAME_DATABASE_MISOFT_URL = "db.misoft.url";
    private static final String PROPERTY_NAME_DATABASE_MISOFT_USERNAME = "db.misoft.username";

    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

    @Resource
    private Environment env;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
        dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
        dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
        dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));

        return dataSource;
    }

    @Bean
    public DataSource dataSourceMISOFT() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_MISOFT_DRIVER));
        dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_MISOFT_URL));
        dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_MISOFT_USERNAME));
        dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_MISOFT_PASSWORD));

        return dataSource;
    }

    private Properties hibProperties() {
        Properties properties = new Properties();
        properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
        properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
        return properties;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource());
        sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
        sessionFactoryBean.setHibernateProperties(hibProperties());
        return sessionFactoryBean;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactoryMISOFT() {
        LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSourceMISOFT());
        sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
        sessionFactoryBean.setHibernateProperties(hibProperties());
        return sessionFactoryBean;
    }
}
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.miso.vre.model.VRE_Record;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

@Repository
public class VRETestTableDAOImpl implements VRETestTableDAO {

    @Autowired
    @Qualifier(value="sessionFactoryMISOFT")
    private SessionFactory sessionFactoryMISOFT;

    private Session getCurrentSession() {
        return sessionFactoryMISOFT.getCurrentSession();
    }

    public VRE_Record getVRE_Record(int id) {
        VRE_Record vRE_Record = (VRE_Record) getCurrentSession().get(VRE_Record.class, id);
        return vRE_Record;
    }
}
package org.miso.vre.service;

import org.miso.vre.dao.VRETestTableDAO;
import org.miso.vre.model.VRE_Record;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by PDuer on 12/29/2015.
 */
@Service
@Transactional
public class TestServiceImpl implements TestService {

    @Autowired
    private VRETestTableDAO vreTestTableDAO;

    @Override
    public VRE_Record getVRERecord (int id) {
        return vreTestTableDAO.getVRE_Record(id);
    }
}

异常org . spring framework . web . util . nestedservletexception:请求处理失败;嵌套html" target="_blank">异常为org . hibernate . hibernate exception:未找到当前线程的会话org . spring framework . web . servlet . framework servlet . processrequest(framework servlet . Java:943)org . spring framework . web . servlet . framework servlet . doget(framework servlet . Java:822)javax . servlet . http . http servlet . service(http servlet . Java:622)org . spring framework . web . servlet . framework servlet . service(framework servlet .

根本原因org.hibernate.HibernateException:未找到当前线程的会话org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1013)org.miso.vre.dao.VRETestTableDAOImpl.getCurrentSession(VRETestTableDAOImpl.java:18)org.miso.vre.dao.VRETestTableDAOImpl.getVRE_Record(VRETestTableDAOImpl.java:22)org.miso.vre.service.TestServiceImpl.getVRERecord(TestServiceImpl.java:22)sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

共有1个答案

易自珍
2023-03-14

原因是,sessionFactoryMISOFT不与任何事务管理器相关联。只有sessionFactory通过transactionManager()方法与事务管理器相关联。

您需要创建一个类似的方法,例如,事务管理器MISOFT()并将会话工厂软件与此新事务管理器相关联。

当使用@Transaction属性时,我们需要指定需要使用哪个transactionManager。

在我的情况下,我定义了两个会话工厂和两个事务管理器方法,如下所示:

@Bean
public HibernateTransactionManager transactionManagerABC() {
    return new HibernateTransactionManager(sessionFactoryABC().getObject());
}

@Bean
public HibernateTransactionManager transactionManagerXYZ() {
    return new HibernateTransactionManager(sessionFactoryXYZ().getObject());
}   

在使用它时,我在您的服务类中指定transactionManagerABC或transactionManagerXYZ以及Transactional属性,如下所示:

@Transactional(transactionManager="transactionManagerABC")
public Forest getForestById(int id) {
    return forestDAO.getForestById(id);
}

您需要对sessionFactory使用带有自动连接注释的限定符,我相信您已经有了:

@Qualifier("sessionFactoryABC")
private SessionFactory sessionFactory;
 类似资料:
  • 问题内容: 我有一个使用spring和hibernate的java stuts2 Web应用程序。 我越来越。 SpringBean.xml hibernate.cfg.xml CustomerServiceImpl.java CustomerDaoImpl.java CustomerAction.java 我得到的例外 问题答案: 您在Spring配置中指定了一个事务管理器,但是没有关于何时或何

  • 我一直在为Web应用程序的一个非常常见的用例而烦恼。我有一个使用REST存储库、JPA等的Spring-Boot应用程序。问题是我有两个数据源: 包含用户身份验证信息的嵌入式H2数据源 因为第二个数据源特定于经过身份验证的用户,所以我正在尝试使用AbstractRoutingDataSource在身份验证后根据主体用户路由到正确的数据源。 让我抓狂的是,Spring Boot在启动时拼命地让我实例

  • 问题内容: 我有一个使用spring和hibernate的java stuts2 Web应用程序。 我越来越。 SpringBean.xml hibernate.cfg.xml CustomerServiceImpl.java CustomerDaoImpl.java CustomerAction.java 我得到的例外 问题答案: 您在Spring配置中指定了一个事务管理器,但是没有关于何时或何

  • 我得到以下错误 服务级别 刀类钻头 这个在我application-context.xml 有人能指出为什么我会得到下面的错误吗?

  • 问题内容: 我正在使用Spring和Hibernate,Spring的配置如下。如何配置两个数据源, session factories。使用注释管理事务。请指教 问题答案: 在Hibernate DAO中,我们可以使用@Qualifier注释,如下所示连接2个会话工厂

  • 我对卡桑德拉完全陌生,所以我的错误可能很明显。 我试图创建一个应用程序与Spring启动(版本2.3.0. M2),联系安装在localhost的cassandra(版本3.11.6)。 我收到一条消息java.lang.IllegalStateException:由于您提供了显式接触点,因此必须显式设置本地DC(请参阅配置中的basic.load-balancing-policy.local-d