web-dev-qa-db-fra.com

Hibernate en utilisant plusieurs bases de données

Quelqu'un sait comment ajouter une autre source de données dans la configuration de veille prolongée et comment configurer Spring pour que cette source de données se lance automatiquement dans mon DAO respectif?

Ceci est mon code avec une source de données, qui fonctionne parfaitement, mais je ne sais pas comment ajouter une autre source de données. Je veux ajouter une autre source de données qui est une base de données avec des tables différentes de la base de données réelle.

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 EXEMPLE

@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();
    }
13
richardhell

d'accord. Je trouve une autre solution, qui utilise la même méthode que celle-ci: ajoutez une autre source de données et SessionFactory, ensuite dans la méthode de DAO qui injjecte la sessionFactory, ajoutez l’annotation @Qualifier avec la propriété de la sessionFactory requise, comme ceci: 

  @Autowired 
    public ProgramaSgteDAOHibernate(@Qualifier("sessionFactory3") SessionFactory sessionFactory) { 
     super(sessionFactory); 
    }
9
richardhell

Je suppose que vous avez un ensemble de DAO qui devrait utiliser dataSource1 et le sessionFactory1 approprié, tandis que d'autres devraient utiliser différents dataSouce2 et sessionFactory2 en fonction de dataSource2. Bien sûr, vous devez déclarer votre deuxième variable dataSource et d'autres beans: copiez simplement la configuration que vous avez déjà et changez les identifiants de bean afin qu'ils ne se rencontrent pas. Tout devrait être mis en miroir sauf <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"/>

Et voici le vrai problème: vous avez maintenant deux gestionnaires de transactions liés à des fabriques de sessions différentes, qui à leur tour sont routées vers différentes sources de données. Mais les annotations @Transactional n'utiliseront toujours qu'un seul gestionnaire de transactions - celui nommé transactionManager par défaut (remarque: j'ai explicitement pointé transactionManager1. Cela signifie que les DAO utilisant une deuxième source de données participeront aux transactions démarrées dans la première source de données - ce n'est évidemment pas ce que l'on voulait.

Il existe certaines solutions de contournement, comme définir explicitement le nom du gestionnaire de transactions dans l'annotation @Transactional (jamais essayé) ou utiliser TransactionTemplate, mais comme vous pouvez le constater, le problème doit être bien réfléchi.

En ce qui concerne le câblage automatique, si vous nommez le réseau par nom, attribuez à vos champs le même nom que les fabriques de session ou les identifiants de sources de données. Cela devrait fonctionner, mais c’est votre plus petit problème.

12
Tomasz Nurkiewicz

J'ai eu le même problème. J'ai résolu ce problème en créant: ApplicationContext.xml

<!-- dataSource properies -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:dataSource.properties" />
</bean>

<!-- MySQL -->
<bean id="mySQLdataSource" class="org.Apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${mySql.driverClassName}" />
    <property name="url" value="${mySql.url}" />
    <property name="username" value="${mySql.username}" />
    <property name="password" value="${mySql.password}" />
</bean>
<bean id="mySQLsessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="mySQLdataSource" />
    <property name="packagesToScan" value="com.victor.entity" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${mySql.dialect}</prop>
        </props>
    </property>
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>

<bean id="mySQLtransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySQLsessionFactory" />
</bean>
<tx:annotation-driven proxy-target-class="true"
    transaction-manager="mySQLtransactionManager" />

<!-- Oracle -->
<bean id="oracleDataSource" class="org.Apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${Oracle.driverClassName}" />
    <property name="url" value="${Oracle.url}" />
    <property name="username" value="${Oracle.username}" />
    <property name="password" value="${Oracle.password}" />
</bean>
<bean id="oracleSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="oracleDataSource" />
    <property name="packagesToScan" value="com.victor.entity" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${Oracle.dialect}</prop>
        </props>
    </property>
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>
<tx:annotation-driven proxy-target-class="true"
    transaction-manager="oracleTransactionManager" />
<bean id="oracleTransactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="oracleSessionFactory" />
</bean>

dans Dao injecté sessionFactory avec annotation Qualifier. Dans mon cas, j'avais BaseEnity générique:

public abstract class BaseEntityDAOImpl<T extends BaseEntity> implements BaseEntityDAO<T> {

private Class<T> persistentClass;
@Autowired
@Qualifier("oracleSessionFactory")
SessionFactory sessionFactory;
}

et en service en utilisant l'annotation:

@Service
@Transactional(propagation = Propagation.REQUIRED, readOnly = true, value = "oracleTransactionManager")
public class UserService {

@Autowired
private UserDAO dao;
}

Averythings wokrs bien.

4
Victor1125

Je sais que je suis en retard pour répondre, cependant, j'ai résolu le problème (comment connecter plusieurs bases de données en utilisant spring et Hibernate) de cette manière, j'espère que cela vous aidera :) 

NOTE: I have added the relevant code, kindly make the dao and rest with the help of impl I used in the below mentioned code.

**web.xml**

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://Java.Sun.com/xml/ns/javaee" xmlns:web="http://Java.Sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee http://Java.Sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>MultipleDatabaseConnectivityInSpring</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
     <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <load-on-startup>1</load-on-startup>
    </servlet>
     <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/dispatcher-servlet.xml
        </param-value>
    </context-param>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>


**persistence.xml**


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://Java.Sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://Java.Sun.com/xml/ns/persistence http://Java.Sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="localPersistenceUnitOne"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>in.india.entities.CustomerDetails</class>
        <exclude-unlisted-classes />
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
            <property name="hibernate.jdbc.batch_size" value="0" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/shankar?sslmode=require" />
            <property name="hibernate.connection.username" value="username" />
            <property name="hibernate.connection.password" value="password" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
    <persistence-unit name="localPersistenceUnitTwo"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>in.india.entities.CompanyDetails</class>
        <exclude-unlisted-classes />
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
            <property name="hibernate.jdbc.batch_size" value="0" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/shankarTwo?sslmode=require" />
            <property name="hibernate.connection.username" value="username" />
            <property name="hibernate.connection.password" value="password" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>


**dispatcher-servlet**


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
    default-autowire="byName"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
      http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
      http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc 
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <!-- Configure messageSource -->

    <mvc:annotation-driven />
    <context:component-scan base-package="in.india.*" />
    <bean id="messageResource"
        class="org.springframework.context.support.ResourceBundleMessageSource"
        autowire="byName">
        <property name="basename" value="messageResource"></property>
    </bean>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>



    <bean id="entityManagerFactoryOne"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        autowire="constructor">
        <property name="persistenceUnitName" value="localPersistenceUnitOne" />
    </bean>

    <bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource"
        autowire="byName">
        <property name="basename" value="messageResource" />
    </bean>

    <bean id="entityManagerFactoryTwo"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        autowire="constructor">
        <property name="persistenceUnitName" value="localPersistenceUnitTwo" />
    </bean>

    <bean id="manager1" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoryOne" />
    </bean>

    <bean id="manager2" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoryTwo" />
    </bean>

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

    <!-- declare dependies here -->

    <bean class="in.india.service.dao.impl.CustomerServiceImpl" />
    <bean class="in.india.service.dao.impl.CompanyServiceImpl" />

    <!-- Configure MVC annotations -->
    <bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    <bean
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</beans>



**Java class to persist into one database**


package in.india.service.dao.impl;

import in.india.entities.CompanyDetails;
import in.india.service.CompanyService;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Transactional;

public class CompanyServiceImpl implements CompanyService {

    @PersistenceContext(unitName = "entityManagerFactoryTwo")
    EntityManager entityManager;

    @Transactional("manager2")
    @Override
    public boolean companyService(CompanyDetails companyDetails) {

        boolean flag = false;
        try 
        {
            entityManager.persist(companyDetails);
            flag = true;
        } 
        catch (Exception e)
        {
            flag = false;
        }

        return flag;
    }

}


**Java class to persist in another database** 

package in.india.service.dao.impl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Transactional;

import in.india.entities.CustomerDetails;
import in.india.service.CustomerService;

public class CustomerServiceImpl implements CustomerService {

    @PersistenceContext(unitName = "localPersistenceUnitOne")
    EntityManager entityManager;

    @Override
    @Transactional(value = "manager1")
    public boolean customerService(CustomerDetails companyData) {

        boolean flag = false;
        entityManager.persist(companyData);
        return flag;
    }
}


**customer.jsp**

<%@page language="Java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <center>
        <h1>SpringWithMultipleDatabase's</h1>
    </center>
    <form:form method="GET" action="addCustomer.htm"  modelAttribute="customerBean" >
        <table>
            <tr>
                <td><form:label path="firstName">First Name</form:label></td>
                <td><form:input path="firstName" /></td>
            </tr>
            <tr>
                <td><form:label path="lastName">Last Name</form:label></td>
                <td><form:input path="lastName" /></td>
            </tr>
            <tr>
                <td><form:label path="emailId">Email Id</form:label></td>
                <td><form:input path="emailId" /></td>
            </tr>
            <tr>
                <td><form:label path="profession">Profession</form:label></td>
                <td><form:input path="profession" /></td>
            </tr>
            <tr>
                <td><form:label path="address">Address</form:label></td>
                <td><form:input path="address" /></td>
            </tr>
            <tr>
                <td><form:label path="age">Age</form:label></td>
                <td><form:input path="age" /></td>
            </tr>
            <tr>
                <td><input type="submit" value="Submit"/></td>
             </tr>
        </table>
    </form:form>
</body>
</html>


**company.jsp**


<%@ page language="Java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ScheduleJobs</title>
</head>
<body>
 <center><h1>SpringWithMultipleDatabase's</h1></center>
 <form:form method="GET" action="addCompany.htm"  modelAttribute="companyBean" >
 <table>
    <tr>
        <td><form:label path="companyName">Company Name</form:label></td>
        <td><form:input path="companyName" /></td>
    </tr>
    <tr>
        <td><form:label path="companyStrength">Company Strength</form:label></td>
        <td><form:input path="companyStrength" /></td>
    </tr>
    <tr>
        <td><form:label path="companyLocation">Company Location</form:label></td>
        <td><form:input path="companyLocation" /></td>
    </tr>
     <tr>
        <td>
            <input type="submit" value="Submit"/>
        </td>
    </tr>
 </table>
 </form:form>
</body>
</html>

**index.jsp**

<%@ page language="Java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>
 <center><h1>Multiple Database Connectivity In Spring sdfsdsd</h1></center>

<a href='customerRequest.htm'>Click here to go on Customer page</a>
<br>
<a href='companyRequest.htm'>Click here to go on Company page</a>
</body>
</html>

**success.jsp**

<%@ page language="Java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ScheduleJobs</title>
</head>
<body>
 <center><h1>SpringWithMultipleDatabase</h1></center>
    <b>Successfully Saved</b>
</body>
</html>

**CompanyController**

package in.india.controller;

import in.india.bean.CompanyBean;
import in.india.entities.CompanyDetails;
import in.india.service.CompanyService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class CompanyController {

    @Autowired
    CompanyService companyService;

    @RequestMapping(value = "/companyRequest.htm", method = RequestMethod.GET)
    public ModelAndView addStudent(ModelMap model) {
        CompanyBean companyBean = new CompanyBean();
        model.addAttribute(companyBean);
        return new ModelAndView("company");
    }

    @RequestMapping(value = "/addCompany.htm", method = RequestMethod.GET)
    public ModelAndView companyController(@ModelAttribute("companyBean") CompanyBean companyBean, Model model) {
        CompanyDetails  companyDetails = new CompanyDetails();
        companyDetails.setCompanyLocation(companyBean.getCompanyLocation());
        companyDetails.setCompanyName(companyBean.getCompanyName());
        companyDetails.setCompanyStrength(companyBean.getCompanyStrength());
        companyService.companyService(companyDetails);
        return new ModelAndView("success");

    }
}

**CustomerController**


package in.india.controller;

import in.india.bean.CustomerBean;
import in.india.entities.CustomerDetails;
import in.india.service.CustomerService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class CustomerController {

    @Autowired
    CustomerService customerService;

    @RequestMapping(value = "/customerRequest.htm", method = RequestMethod.GET)
    public ModelAndView addStudent(ModelMap model) {
        CustomerBean customerBean = new CustomerBean();
        model.addAttribute(customerBean);
        return new ModelAndView("customer");
    }

    @RequestMapping(value = "/addCustomer.htm", method = RequestMethod.GET)
    public ModelAndView customerController(@ModelAttribute("customerBean") CustomerBean customer, Model model) {
        CustomerDetails customerDetails = new CustomerDetails();
        customerDetails.setAddress(customer.getAddress());
        customerDetails.setAge(customer.getAge());
        customerDetails.setEmailId(customer.getEmailId());
        customerDetails.setFirstName(customer.getFirstName());
        customerDetails.setLastName(customer.getLastName());
        customerDetails.setProfession(customer.getProfession());
        customerService.customerService(customerDetails);
        return new ModelAndView("success");

    }
}


**CompanyDetails Entity**


package in.india.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "company_details")
public class CompanyDetails {

    @Id
    @SequenceGenerator(name = "company_details_seq", sequenceName = "company_details_seq", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "company_details_seq")
    @Column(name = "company_details_id")
    private Long companyDetailsId;
    @Column(name = "company_name")
    private String companyName;
    @Column(name = "company_strength")
    private Long companyStrength;
    @Column(name = "company_location")
    private String companyLocation;

    public Long getCompanyDetailsId() {
        return companyDetailsId;
    }

    public void setCompanyDetailsId(Long companyDetailsId) {
        this.companyDetailsId = companyDetailsId;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Long getCompanyStrength() {
        return companyStrength;
    }

    public void setCompanyStrength(Long companyStrength) {
        this.companyStrength = companyStrength;
    }

    public String getCompanyLocation() {
        return companyLocation;
    }

    public void setCompanyLocation(String companyLocation) {
        this.companyLocation = companyLocation;
    }
}


**CustomerDetails Entity**

package in.india.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "customer_details")
public class CustomerDetails {

    @Id
    @SequenceGenerator(name = "customer_details_seq", sequenceName = "customer_details_seq", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customer_details_seq")
    @Column(name = "customer_details_id")
    private Long customerDetailsId;
    @Column(name = "first_name ")
    private String firstName;
    @Column(name = "last_name ")
    private String lastName;
    @Column(name = "email_id")
    private String emailId;
    @Column(name = "profession")
    private String profession;
    @Column(name = "address")
    private String address;
    @Column(name = "age")
    private int age;
    public Long getCustomerDetailsId() {
        return customerDetailsId;
    }

    public void setCustomerDetailsId(Long customerDetailsId) {
        this.customerDetailsId = customerDetailsId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    public String getProfession() {
        return profession;
    }

    public void setProfession(String profession) {
        this.profession = profession;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
2

J'ai eu le même problème. Je l'ai résolu comme ça:

Tout d’abord, il devrait exister différents fichiers cfg.xml pour différentes bases de données. Ensuite, utilisez simplement l’objet Configuration de Hibernate chaque fois que vous souhaitez vous connecter à votre deuxième base de données. 

Configuration config = new Configuration().configure("<complete path to your cfg.xml file>");
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

J'ai trouvé ceci ici: http://www.coderanch.com/t/468821/ORM/Java/If-hibernate-cfg-xml-has

Je suis à peu près sûr que cela peut être étendu à plus de 2 bases de données. J'espère que cela vous aidera.

2
Bhushan

Bien. Enfin, j'ai résolu mon problème de cette façon:

Premièrement: ajoutez une autre source de données et sessionFactory. 

Deuxièmement: ajoutez à la fin de la configuration d'hibernate un bean à chaque DAO qui utilise une autre sessionFactory (implicite, une autre source de données). Comme ça:

<bean id="courseDAO" class="com.app.CourseDAOHibernate">
        <property name="sessionFactory" ref="sessionFactory2"/>
    </bean>

Chaque DAO qui utilise une "sessionFactory" est automatiquement détecté, mais dans le cas où d'autres DAO utilisent une autre source de données, vous devriez explicitement aimer cet exemple.

En fin de compte, je ne sais pas si c'est une solution réussie mais cela fonctionne pour moi.

1
richardhell

Je vais ajouter mon exemple aussi. Peut-être que ce sera utile dans d'autres situations, comme obtenir des données d'une base de données et les écrire dans une autre avec EntityManager.

Donc, mon applicationContext.xml :

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

<!-- Connection 1 -->

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="persistenceUnitName" value="unitRemote" />
  <property name="packagesToScan" value="business.domain" />
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="Oracle.jdbc.driver.OracleDriver" />
  <property name="url" value="jdbc:Oracle:thin:@remote_Host:1521:xe" />
  <property name="username" value="USER" />
  <property name="password" value="PASSWORD" />
</bean>


<!-- Connection 2 -->

<bean id="transactionManagerLocal" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactoryLocal" />
</bean>

<bean id="entityManagerFactoryLocal" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSourceLocal" />
  <property name="persistenceUnitName" value="unitLocal" />
  <property name="packagesToScan" value="local.business.domain" />
</bean>

<bean id="dataSourceLocal" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="Oracle.jdbc.driver.OracleDriver" />
  <property name="url" value="jdbc:Oracle:thin:@localhost:1521:xe" />
  <property name="username" value="USER_LOC" />
  <property name="password" value="PASSWORD_LOC" />
</bean>

Le package business.domain a des classes d'entité pour remote connection.

Le package local.business.domain a des entités pour local connection.

Les entités ont des mappages d'annotation pour les colonnes et les relations.

Alors 2 DAO classes:

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class RemoteDao {

  @PersistenceContext(unitName="unitRemote")
  protected EntityManager em;

  // ...

}

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(value="transactionManagerLocal")
public class LocalDao {

  @PersistenceContext(unitName="unitLocal")
  protected EntityManager em;

  // ...

}

Avec cela, je pourrais utiliser @Autowired pour injecter des DAO dans mon JUnit test :

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/config/applicationContext.xml" })
public class DaoTest {

  @Autowired
  private RemoteDao remoteDao;

  @Autowired
  private LocalDao localDao;


  @Test
  public void daoTest(){
    Entity entity = remoteDao.find(id);
    localDao.persist(entity);
  }

}

Il est donc possible d'utiliser des DAO sans service si cela est nécessaire pour des applications simples, des tests ou des scripts de migration de base de données.

1
mortalis

J'ai été capable de faire cela avec quelque chose comme ci-dessous. 

  • 2 sources de données, 2 sessionFatory, 2 transactionManger et 2 tx: pilotées par des annotations. Et chaque détail de base de données en contexte
  • Celui qui doit être utilisé par défaut doit définir primaire = true. (dans cette connexion oracleDataSource, la connexion est par défaut et la connexion abcDataSource est requise pour l'annotation transactionnelle)

<bean id="oracleDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="Java:env/jdbc/Oracle"/>
</bean>

<bean id="oracleSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" primary="true">
</bean>

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

<bean id="abcDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="Java:env/abc/Oracle"/>
</bean>

<bean id="abcSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="dataSource" ref="abcDataSource"/>
</bean>

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

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

La variable transactionManger pour la fabrique de session par défaut sera disponible par défaut (la valeur par défaut est primaire = true) et pour les autres éléments à spécifier dans l'annotation Transactional


@Service("ABCRead")
@Transactional(value = "abcTransactionManager") 
public class ABCRead {
  @Autowired
  AbcImpl abcImpl;   // this will connect to abcSessionFactory

  @Autowired
  XYZImpl xyzImpl;  // This will connect to oracleSessionFactory

@Service
@Repository
@Transactional("abcTransactionManager")
public class AbcImpl {
  @Autowired
  private SessionFactory sessionFactory;

@Service
public class XYZImpl {
  @Autowired
  private SessionFactory sessionFactory;
0
Vik18