web-dev-qa-db-fra.com

Configuration de plusieurs bases de données avec plusieurs entités entitymanagerfactory dans spring data jpa

Je souhaite configurer 2 usines de gestionnaire d'entités pour 2 bases de données différentes (serveur Postgres et SQL) au printemps 4.

persistence.xml contient 2 unités de persistance pour 2 bases de données:

 <?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://Java.Sun.com/xml/ns/persistence">
    <persistence-unit name="entityManager">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.hbm2ddl.auto" value="validate"/>
            <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
        </properties>
    </persistence-unit>

    <persistence-unit name="sqlEntityManager">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.hbm2ddl.auto" value="validate"/>
            <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
        </properties>
    </persistence-unit>
</persistence>

spring-context.xml contient 2 sources de données et 2 fabriques entitymanager:

    <bean id="postgresDataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource"
          p:driverClassName="org.postgresql.Driver"
          p:url="jdbc:postgresql://localhost:5432/test?createDatabaseIfNotExist=true"
          p:username="test"
          p:password="test"/>

    <bean id="sqlDataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource"
          p:driverClassName="com.Microsoft.sqlserver.jdbc.SQLServerDriver"
          p:url="jdbc:sqlserver://localhost:1433;databaseName=test"
          p:username="test"
          p:password="test"/>


    <bean id="persistenceUnit" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="persistenceXmlLocations">
            <list>
                <value>classpath*:META-INF/persistence.xml</value>
            </list>
        </property>
        <property name="defaultDataSource" ref="postgresDataSource"/>
    </bean>

    <bean id="sqlPersistenceUnit" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="persistenceXmlLocations">
            <list>
                <value>classpath*:META-INF/persistence.xml</value>
            </list>
        </property>
        <property name="defaultDataSource" ref="sqlDataSource"/>
    </bean>



    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="persistenceUnit"/>
        <property name="persistenceUnitName" value="entityManager"/>
<property name="packagesToScan" value="com.test.entities.postgres"/>
    </bean>

    <bean id="sqlEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="sqlPersistenceUnit"/>
        <property name="persistenceUnitName" value="sqlEntityManager"/>
<property name="packagesToScan" value="com.test.entities.sql"/>
    </bean>

Lorsque j'ai lancé l'application, il n'a pas pu créer entitymangerfactory car il vérifie la présence de tables dans postgres qui se trouvent dans le serveur SQL.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/spring-context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Missing table:<SqlServerTableName>
8
user1188867

Je suis en mesure de résoudre le problème en supprimant persistence.xml et en créant entitymanagerfactory et pchentitymanagerfactory dans context.xml comme ci-dessous:

<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      p:dataSource-ref="phoenixDataSource">
    <property name="packagesToScan">
        <array>
            <value>com.test.entities.postgres</value>
        </array>
    </property>

    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>

    </bean>

parce que packagesToScan ne fonctionne pas si nous utilisons persistence.xml.

10
user1188867

Veuillez mettre à jour votre configuration Hibernate par ceci. Je pense que cela vous aiderait

<property name="hibernate.hbm2ddl.auto">create</property>
or 
<property name="hibernate.hbm2ddl.auto">update</property>
2
Devendra Singh

J'ai une application avec deux entitymanager. C'est ma config:

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

    <persistence-unit name="myapp" transaction-type="RESOURCE_LOCAL">
        <class>...</class>
        <class>...</class>
    </persistence-unit>

    <persistence-unit name="proxies" transaction-type="RESOURCE_LOCAL">
        <class>...</class>
        <class>...</class>
    </persistence-unit>

</persistence>

spring-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

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

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

    <bean id="transactionManagerProxy" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="dataSource" ref="proxyDataSource" />
        <property name="entityManagerFactory" ref="entityManagerFactoryProxy" />
    </bean>

    <jpa:repositories base-package="com.example.myapp.repository" entity-manager-factory-ref="entityManagerFactory" />
    <jpa:repositories base-package="com.example.myapp.repository.proxy" entity-manager-factory-ref="entityManagerFactoryProxy" />

    <task:annotation-driven />

    <!-- holding properties for database connectivity /-->
   <context:property-placeholder location="classpath:database.properties"/>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="packagesToScan" value="com.example.myapp.model" />
        <property name="persistenceUnitName" value="myapp" />
        <property name="dataSource" ref="myappDataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    </bean>

    <bean id="entityManagerFactoryProxy" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="packagesToScan" value="com.example.myapp.model.proxy" />
        <property name="persistenceUnitName" value="proxy" />
        <property name="dataSource" ref="proxyDataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    </bean>

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="database" value="MYSQL"/>
        <property name="showSql" value="false"/>
        <property name="generateDdl" value="false"/>
        <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
    </bean>

    <bean id="dataSource" abstract="true" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
        <property name="minPoolSize" value="${jdbc.minPoolSize}" />
        <property name="maxStatements" value="${jdbc.maxStatements}" />
        <property name="testConnectionOnCheckout" value="${jdbc.testConnectionOnCheckout}" />
        <property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"/>
        <property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
        <property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
        <property name="preferredTestQuery" value="${jdbc.preferredTestQuery}"/>
    </bean>

    <bean id="myappDataSource" parent="dataSource">
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="proxyDataSource" parent="dataSource">
        <property name="jdbcUrl" value="${jdbc.proxy.url}" />
        <property name="user" value="${jdbc.proxy.username}" />
        <property name="password" value="${jdbc.proxy.password}" />
    </bean>

</beans>

J'ai 2 connexions à MySql, mais il devrait être identique pour deux bases de données différentes.

1
Alberto