Reputation: 299
I've a Java Web Service with hibernate spring integration. In my project, I need to connect two same database but different locations. I need to update contents in each projects so i have configured Hibernate sessions with these databases but when i try to insert content in two databases, sessions created for one db connection another one return "org.hibernate.HibernateException: No Session found for current thread". is there any changes needed in my code? Thanks in advance.
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;
}}
In this DAO implementation class, proFetchDAO.save(smsDO) works fine but when proFetchDAO.saveTwo(smsDO) executes it returns "org.hibernate.HibernateException: No Session found for current thread".
stack traces:
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)
Upvotes: 1
Views: 670
Reputation: 961
Ok, so you are using Spring's <tx:annotation-driven />
but I cannot see any of the @Transactional
annotations.
Maybe you could try splitting the method for persisting entity into two separate ones, and annotating each other with @Transactional("transactionManager")
and @Transactional("transactionManagerTwo")
.
Please read the @Transactional
usage documentation.
Upvotes: 1