2015-12-29 18 views
0

我正在使用Spring 4與Hibernate 4並嘗試配置多個數據源。當我使用新的第二個時,我總是得到一個錯誤。使用Hibernate的Spring多重數據源給出:未發現會話錯誤

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.springframework.web.util.NestedServletException:請求 處理失敗;嵌套異常是 org.hibernate.HibernateException:找不到當前線程的會話 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:943) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet。的java:822) javax.servlet.http.HttpServlet.service(HttpServlet.java:622) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807) javax.servlet.http.HttpServlet.service (HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java :73)

根源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.DelegatingMethodA ccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

+1

請將所有代碼簡化爲演示您的問題的MVCE。目前,真的太多了。請參閱http://stackoverflow.com/help/mcve – kebs

回答

0

其原因是,該sessionFactoryMISOFT不與任何事務管理有關。只有sessionFactory通過transactionManager()方法與交易管理器關聯。

您需要創建一個類似的方法,例如transactionManagerMISOFT()並將sessionFactoryMISOFT與此新的transactionManager關聯。

而當使用@Transaction屬性時,我們需要指定需要使用哪個transactionManager。

就我而言,我定義了兩個sessionFactories和兩種事務管理方法如下:

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

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

雖然使用它,我在你的服務類指定要麼transactionManagerABC或transactionManagerXYZ與事務屬性一起,如下:

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

您需要使用預選賽自動裝配Autowired註解爲SessionFactory對象,我相信你已經有了:

@Qualifier("sessionFactoryABC") 
private SessionFactory sessionFactory; 
相關問題