Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate using multiple databases

Someone know how to add a another datasource in hibernate configuration and how to configure Spring to that datasource its autoinject in my respective DAO?

This is my code with one datasource, that run perfectly, but i don't know how add another datasource. I want to add another data source that is a database with different tables than the actual database.

HIBERNATE CONF

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url" value="jdbc:mysql://localhost/personal"/>
        <property name="username" value="root"/>
        <property name="password" value="mysql"/>
    </bean>


    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.app.personal.model</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>

DAO EXAMPLE

@Repository
public class ModuloDAOHibernate extends HibernateTemplate implements ModuloDAO {

    @Autowired
    public ModuloDAOHibernate(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    public List<Modulo> getAllGrupoModuloDAO() {
        Criteria criteriaList = this.getSession().createCriteria(Modulo.class);
        criteriaList.addOrder(Order.asc("orden"));
        return criteriaList.list();
    }
like image 689
richardhell Avatar asked Apr 30 '11 18:04

richardhell


People also ask

Can hibernate connect to multiple databases?

In hibernate we can interact with multiple databases within the same application. All we need is to create two different session factories; one to interact with each database.

Do we need different versions of hibernate to connect different databases?

To communicate with another database server, you need another hibernate configuration file similar to hibernate. cfg. xml. For example, let's say we have a MySQL database server and a Microsoft SQL database server that will be used in an application.

Can we create two SessionFactory in hibernate?

Usually one session factory should be created for one database. When you have multiple databases in your application you should create multiple SessionFactory object. SessionFactory sc=cfg.

Can we have multiple database in spring boot?

Multiple Databases in Spring BootSpring Boot can simplify the configuration above. Now we have defined the data source properties inside persistence-multiple-db-boot. properties according to the Boot autoconfiguration convention.


1 Answers

I assume you have a set of DAOs that should use dataSource1 and appropriate sessionFactory1, while others should use different dataSouce2 and sessionFactory2 based on dataSource2. Of course you need to declare your second dataSource and other beans: simply copy the configuration you already have and change bean ids so they won't collide. Everything should be mirrored except <tx:annotation-driven/>:

<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- ... -->
</bean>

<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource1"/>
    <!-- ... -->
</bean>

<bean id="transactionManager1" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory1"/>
    <!-- ... -->
</bean>


<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- ... -->
</bean>

<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource2"/>
    <!-- ... -->
</bean>

<bean id="transactionManager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory2"/>
    <!-- ... -->
</bean>

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

And here comes the real problem: you now have two transaction managers bound to different session factories, which in turns are routed to different data sources. But @Transactional annotations will always use only one transaction manager - the one named transactionManager by default (note I explicitly pointed transactionManager1. This means that DAOs using second data source will participate in transactions started within first data source - this is obviously not what intended.

There are some workaround to this, like explicitly defining transaction manager name in @Transactional annotation (never tried it) or using TransactionTemplate, but as you can see problem should be well thought.

As for autowiring - if you autowire by name, name your fields the same as session factories or data sources ids and it should work - but is your smallest problem actually.

like image 183
Tomasz Nurkiewicz Avatar answered Oct 18 '22 13:10

Tomasz Nurkiewicz