0

I have 2 different databases in my application,(I'm using spring Mvc``hibernate ) One in localhost and the other is a remote Database. do I have the possibility to declare two datasources in the dispacher Servlet as follow:

 <context:component-scan base-package="com.testcode.controller" />
    <context:component-scan base-package="com.testcode.services" />
    <context:component-scan base-package="com.testcode.dao" />

 <bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView" />

    <property name="prefix">
        <value>/WEB-INF/views/jsp/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

<!-- declare beans -->
<bean id="serverService" class="com.testcode.services.ServerServiceImpl">
    <property name="serverDao" ref="serverDao"></property>
</bean>

<bean id="serverDao" class="com.testcode.dao.ServerdaoImpl">
    <property name="sessionFactory" ref="SessionFactory2" />
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/database1" />
    <property name="username" value="root" />
    <property name="password" value="" />
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://192.168.1.8:3306/database2" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="SessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="annotatedClasses">
        <list>
            <value>com.testcode.domain.User</value>


        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
            </prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<bean id="SessionFactory2"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource2" />
    <property name="annotatedClasses">
        <list>
            <value>com.testcode.domain.Server</value>


        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
            </prop>
            <prop key="hibernate.current_session_context_class ">thread</prop>

            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>


<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/images/**" location="/resources/core/images/" />


<mvc:annotation-driven />

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

<bean id="transactionManager2"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="SessionFactory2" />
</bean>

<tx:annotation-driven/>
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:annotation-driven transaction-manager="transactionManager2" />

when I tried to insert a server to the table in the remote database I had this error:

 org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread

this problem is due to the 2 defined datasources or what?

Edit:

this is serverDaoImpl

@Repository("serverDao")
public class ServerdaoImpl implements ServersDao{

 private SessionFactory sessionFactory;
 public void setSessionFactory(SessionFactory sf){

         this.sessionFactory = sf;
     }

@Override
public void insertServer(Server server) {
     Session session = this.sessionFactory.getCurrentSession();
     session.persist(server);
}

 @SuppressWarnings("unchecked")
@Override
public List<Server> getServerList() {
     Session session = this.sessionFactory.getCurrentSession();
        List<Server> serverList = session.createQuery("from servers").list();
        return serverList;
}

@Override
public void updateServer(Server server) {
     Session session = this.sessionFactory.getCurrentSession();
        session.update(server);     
}

and this is serverServiceImpl:

@Service("serverService")
public class ServerServiceImpl implements ServerService {

private ServersDao serverdao;

public void setServerDao(ServersDao serverdao) {
    this.serverdao = serverdao;
}

@Override
@Transactional
public void insertServer(Server server) {
    this.serverdao.insertServer(server);
}

@Override
@Transactional
public List<Server> getServerList() {
    return this.serverdao.getServerList();
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
pietà
  • 760
  • 1
  • 11
  • 37

2 Answers2

1

You haven`t specified transactionManager2 in <tx:annotation-driven transaction-manager="transactionManager" />

Just see to it that you also defined correctly

<mvc:annotation-driven />
<context:component-scan base-package="" />

Also check if <beans:prop key="hibernate.current_session_context_class">thread</beans:prop> has been added in hibernate.properties file

Please specify @Transactional on your Service or DAO method

shankarsh15
  • 1,947
  • 1
  • 11
  • 16
  • I tried to add this ` ` but it didn't work yes I have defined the `base-packages` I will edit the post – pietà May 16 '16 at 15:58
  • check if thread has been defined in hibernate.properties – shankarsh15 May 16 '16 at 16:04
  • I'm using `spring Mvc` I don't have `hibernate.properties file ` `hibernate's `configuration is in the bean having the id : `sessionFactory ` – pietà May 16 '16 at 16:09
  • add thread and always call getCurrentSession() instead of openSession() – shankarsh15 May 16 '16 at 16:11
  • Also annotate your service or dao method with @Transactional – shankarsh15 May 16 '16 at 16:19
  • Thanks a lot for your time, I made the changes you've proposed I have a new error ! `No Session found for current thread ` does this mean that it didn't recognized the `sessionFactory2`? – pietà May 16 '16 at 16:21
  • Please check this post http://stackoverflow.com/questions/20541736/hibernate-configuring-multiple-datasources-and-multiple-session-factories – shankarsh15 May 16 '16 at 16:29
  • my configuration seems to be like the link you've provided.. everything seems to be ok , I don't know why this is not working !! I have tried to `Autowire sessionFactory2` nothing has changed ... I have tried to insert something using the first database with `sessionFactory` it's ok ! but `sessionFactory2` generates error ! – pietà May 17 '16 at 10:14
  • also I have tried to use `openSession` there are no errors but it didn't insert anything into database ! – pietà May 17 '16 at 10:17
  • Thank you for your directions @shankarsh ..they directed me to the best solution :) – pietà May 19 '16 at 15:34
0

I have solved the problem, now I can use both of the 2 datasources. the problem was a conflict between TransactionManager and TransactionManager2

I have added @Transactional(value="TransactionManager2") in the serverService .

hope that this will help someone in the future.

pietà
  • 760
  • 1
  • 11
  • 37