使用多个数据库连接创建Hibernate会话在Java WebService中

时间:2016-04-12 11:38:18

标签: spring hibernate web-services hibernate-mapping

我有一个带有hibernate spring集成的Java Web服务。在我的项目中,我需要连接两个相同的数据库但不同的位置。我需要更新每个项目中的内容,所以我已经配置了这些数据库的Hibernate会话,但是当我尝试在两个数据库中插入内容时,为一个数据库连接创建的会话另一个返回“org.hibernate.HibernateException:找不到当前线程的会话”。我的代码中是否需要进行任何更改?提前谢谢。

的applicationContext.xml

<context:component-scan base-package="com.sas.sakthi.rest" />

<!-- <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
    <property name="basename" value="classpath:messages" /> <property name="defaultEncoding" 
    value="UTF-8" /> </bean> -->
<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="/WEB-INF/jdbc.properties" />

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />

<bean id="dataSourceTwo" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.databaseurltwo}" p:username="${jdbc.usernametwo}"
    p:password="${jdbc.passwordtwo}" />

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="annotatedClasses">
        <list>
            <value>com.sas.sakthi.rest.model.CategoryDO</value>
            <value>com.sas.sakthi.rest.model.ProductDO</value>
            <value>com.sas.sakthi.rest.model.CustomerDO</value>             
            <value>com.sas.sakthi.rest.model.SubCategoryDO</value>
            <value>com.sas.sakthi.rest.model.SmsLogDO</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>
<bean id="sessionFactoryTwo"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSourceTwo" />
    <property name="annotatedClasses">
        <list>
            <value>com.sas.sakthi.rest.model.CategoryDO</value>
            <value>com.sas.sakthi.rest.model.ProductDO</value>
            <value>com.sas.sakthi.rest.model.CustomerDO</value>         
            <value>com.sas.sakthi.rest.model.SubCategoryDO</value>
            <value>com.sas.sakthi.rest.model.SmsLogDO</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<!-- <bean id="AbstractHibernateDAO" class="com.stnage.service.rest.dao.AbstractHibernateDAOImpl"></bean> 
    <bean id="BatchMessageManagerDAO" class="com.stnage.service.rest.dao.BatchMessageManagerDAOImpl"></bean> 
    <bean id="BatchMessageManagerService" class="com.stnage.service.rest.service.BatchMessageManagerServiceImpl"></bean> -->
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:annotation-driven transaction-manager="transactionManagerTwo" />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="transactionManagerTwo"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactoryTwo" />
</bean>

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/sakthi
jdbc.username=root
jdbc.password=XXXXXX
jdbc.databaseurltwo=jdbc:mysql://192.168.2.15:3306/sakthi
jdbc.usernametwo=YYYY
jdbc.passwordtwo=XXXXXX

HibernateDAO.java

    @Autowired
@Qualifier("sessionFactory")
SessionFactory sessionFactory;

@Autowired
@Qualifier("sessionFactoryTwo")
SessionFactory sessionFactoryTwo;

@Override
public void create(BaseModel entity) {
    getCurrentSession().persist(entity);
}

@Override
public void update(BaseModel entity) {
    getCurrentSession().merge(entity);
}

@Override
public void save(BaseModel entity) {
    getCurrentSession().saveOrUpdate(entity);
}

@Override
public void delete(BaseModel entity) {
    getCurrentSession().delete(entity);
}

@Override
public Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
}

@Override
public void refresh(BaseModel entity) {
    getCurrentSession().refresh(entity);
}

@Override
public <T> BaseModel findById(Class<T> entityClass, int entityId) {
    return (BaseModel) getCurrentSession().get(entityClass, entityId);
}

@Override
public void createTwo(BaseModel entity) {
    getCurrentSessionTwo().persist(entity);
}

@Override
public void updateTwo(BaseModel entity) {
    getCurrentSessionTwo().merge(entity);
}

@Override
public void saveTwo(BaseModel entity) {
    getCurrentSessionTwo().saveOrUpdate(entity);
}

@Override
public void deleteTwo(BaseModel entity) {
    getCurrentSessionTwo().delete(entity);
}

@Override
public Session getCurrentSessionTwo() {
    return sessionFactoryTwo.getCurrentSession();
}

@Override
public void refreshTwo(BaseModel entity) {
    getCurrentSessionTwo().refresh(entity);
}

@Override
public <T> BaseModel findByIdTwo(Class<T> entityClass, int entityId) {
    return (BaseModel) getCurrentSessionTwo().get(entityClass, entityId);
}

SmsLogDataFetchServiceImpl.java

@Service
public class SmsLogDataFetchServiceImpl implements 
SmsLogDataFetchService {

@Autowired
ProductDataFetchDAO proFetchDAO;//extends HibernateDAO.java

@Override
public int savenewentry(String msg, String phoneNo, String receivedOn) {
    try {
        if (msg != null || phoneNo != null || receivedOn != null) {
            SmsLogDO smsDO = new SmsLogDO();
            smsDO.setCustomerNo(phoneNo);
            smsDO.setSmsContent(msg);
            smsDO.setCreatedOn(receivedOn);
            smsDO.setStatus(1);
            smsDO.setUpdatedOn((new Date()).toString());
            proFetchDAO.save(smsDO);
            proFetchDAO.saveTwo(smsDO);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 0;
}}

在这个DAO实现类中,proFetchDAO.save(smsDO)工作正常,但是当proFetchDAO.saveTwo(smsDO)执行时,它返回“org.hibernate.HibernateException:找不到当前线程的Session”。

堆栈跟踪:

Hibernate: insert into sms_log (created_by, created_on, customer_no, sms_content, status, updated_by, updated_on) values (?, ?, ?, ?, ?, ?, ?)
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:883)
at com.sas.sakthi.rest.dao.AbstractHibernateDAOImpl.getCurrentSessionTwo(AbstractHibernateDAOImpl.java:84)
at com.sas.sakthi.rest.dao.AbstractHibernateDAOImpl.saveTwo(AbstractHibernateDAOImpl.java:74)
at com.sas.sakthi.rest.service.SmsLogDataFetchServiceImpl.savenewentry(SmsLogDataFetchServiceImpl.java:33)
at com.sas.sakthi.rest.controller.SMSGatewayReceiverController.receiveGatewaySms(SMSGatewayReceiverController.java:48)
at com.sas.sakthi.rest.controller.SMSGatewayReceiverController$$FastClassByCGLIB$$d0f8afce.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at com.sas.sakthi.rest.controller.SMSGatewayReceiverController$$EnhancerByCGLIB$$a5284739.receiveGatewaySms(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:540)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:715)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:205)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:266)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

1 个答案:

答案 0 :(得分:1)

好的,所以你使用的是Spring <tx:annotation-driven />,但我看不到任何@Transactional注释。

也许您可以尝试将持久化实体的方法拆分为两个单独的方法,并使用@Transactional("transactionManager")@Transactional("transactionManagerTwo")对彼此进行注释。

请阅读@Transactional使用文档。