Весна загрузки JPA установить пользовательский источник данных - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть 2 источника данных -

#datasource jndi setup
database.datasources[1].jndi-name=jdbc/yyyy
database.datasources[1].username=yyyy
database.datasources[1].password=yyyyy
database.datasources[1].url=jdbc:oracle:thin:@localhost:2222:webtst
database.datasources[1].driverClassName=oracle.jdbc.OracleDriver
database.datasources[1].factory=org.apache.tomcat.jdbc.pool.DataSourceFactory
database.datasources[1].initialSize=1
database.datasources[1].maxActive=5

database.datasources[0].jndi-name=jdbc/xxx
database.datasources[0].username=xxx
database.datasources[0].password=xxxx
database.datasources[0].url=jdbc:oracle:thin:@localhost:2222:webtst
database.datasources[0].driverClassName=oracle.jdbc.OracleDriver
database.datasources[0].factory=org.apache.tomcat.jdbc.pool.DataSourceFactory
database.datasources[0].initialSize=1
database.datasources[0].maxActive=15 

И 2 совпадающих репозитория JPA, как мне настроить один из них на использование разных ds (не первичных) после того, как я определил один из них как @Основной:

@Bean
@Primary
DataSource dataSource() throws SQLException {
    OracleDataSource dataSource = new OracleDataSource();
    dataSource.setUser(xusername);
    dataSource.setPassword(xpassword);
    dataSource.setURL(xurl);

    dataSource.setImplicitCachingEnabled(true);
    dataSource.setFastConnectionFailoverEnabled(true);
    return dataSource;
}



@Bean
DataSource propsDataSource() throws SQLException {
    OracleDataSource propsDataSource = new OracleDataSource();
    //propsDataSource.setDataSourceName(secJNDIName);
    propsDataSource.setUser(yUserName);
    propsDataSource.setPassword(ypropsPassword);
    propsDataSource.setURL(upropsUrl);
    propsDataSource.setImplicitCachingEnabled(true);
    propsDataSource.setFastConnectionFailoverEnabled(true);
    return propsDataSource;
}

И простой JpaRepository, который я хочу использовать для второго источника данных:

public interface AttributesRepo extends JpaRepository<PRODUCTATTRIBUTE, PRODUCTATTRIBUTE_KEY> {

}

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Я использую два источника данных.Это мое applicationContext.xml:

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:util="http://www.springframework.org/schema/util"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:jpa="http://www.springframework.org/schema/data/jpa"
   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.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx.xsd
   http://www.springframework.org/schema/util
   http://www.springframework.org/schema/util/spring-util.xsd
   http://www.springframework.org/schema/data/jpa
   http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
   http://www.springframework.org/schema/data/jpa
   http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

<jpa:repositories base-package="nl.christine.schwartze.server"/>

<context:property-placeholder location="classpath:/META-INF/database.properties"/>

<context:component-scan base-package="nl.christine.schwartze.server"/>

<bean class="org.apache.commons.dbcp2.BasicDataSource"
      destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${database.driverClassName}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.username}"/>
    <property name="password" value="${database.password}"/>
</bean>

<bean class="org.apache.commons.dbcp2.BasicDataSource"
      destroy-method="close" id="importDataSource">
    <property name="driverClassName" value="${database.driverClassName}"/>
    <property name="url" value="${importDatabase.url}"/>
    <property name="username" value="${database.username}"/>
    <property name="password" value="${database.password}"/>
</bean>

<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="defaultPU"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="nl.christine.schwartze.server.model"/>
    <property name="jpaVendorAdapter" ref="hibernateVendorAdapter"/>
    <property name="jpaProperties" ref="props"/>
    <property name="persistenceProvider">
        <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
    </property>
</bean>

<bean id="importEntityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="importPU"/>
    <property name="dataSource" ref="importDataSource"/>
    <property name="packagesToScan" value="nl.christine.schwartze.server.modelimport"/>
    <property name="jpaVendorAdapter" ref="hibernateVendorAdapter"/>
    <property name="jpaProperties" ref="importprops"/>
    <property name="persistenceProvider">
        <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
    </property>
</bean>

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

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

<bean id="hibernateVendorAdapter"
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

<util:properties id="props">
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
    <prop key="hibernate.hbm2ddl.auto">${database.createorvalidate}</prop>
    <prop key="hibernate.ddl-auto">${database.createorvalidate}</prop>
    <prop key="spring.jpa.show-sql">true</prop>
    <prop key="spring.jpa.generate.ddl">true</prop>
    <prop key="spring.jpa.hibernate.ddl-auto">${database.createorvalidate}</prop>
    <prop key="spring.datasource.initialization-mode">never</prop>
    <prop key="spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation">true</prop>
</util:properties>

<util:properties id="importprops">
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.id.new_generator_mappings">false</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
    <prop key="hibernate.hbm2ddl.auto">validate</prop>
    <prop key="hibernate.ddl-auto">validate</prop>
    <prop key="spring.jpa.show-sql">true</prop>
    <prop key="spring.jpa.generate.ddl">true</prop>
    <prop key="spring.jpa.hibernate.ddl-auto">validate</prop>
    <prop key="spring.datasource.initialization-mode">never</prop>
    <prop key="spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation">true</prop>
</util:properties>

<bean id="importLetterDao" class="nl.christine.schwartze.server.daoimport.impl.ImportLetterDaoImpl" scope="singleton">
</bean>

<bean id="letterDao" class="nl.christine.schwartze.server.dao.impl.LetterDaoImpl" scope="singleton">
</bean>

<bean id="locationDao" class="nl.christine.schwartze.server.dao.impl.LocationDaoImpl" scope="singleton">
</bean>

<bean id="personDao" class="nl.christine.schwartze.server.dao.impl.PersonDaoImpl" scope="singleton">
</bean>

<bean id="letterService" class="nl.christine.schwartze.server.service.impl.LetterServiceImpl" scope="singleton">
</bean>

<bean id="logger" scope="prototype" class="org.slf4j.LoggerFactory" factory-method="getLogger">
    <constructor-arg name="name" value="schwartzeLogger" />
</bean>

Это часть одного из классов домена:

@Entity
@Table(name = "letters")
@EnableJpaRepositories(
    basePackages = "nl.christine.schwartze.server.dao",
    transactionManagerRef = "transactionManager",
    entityManagerFactoryRef = "defaultPU")
public class Letter {
...

Это аннотации, которые я имею для метода Controller:

   @CrossOrigin(origins = "http://pengo.christine.nl:3000")
@RequestMapping(method = RequestMethod.POST, value = "/get_letters/")
@Transactional("transactionManager")
public ResponseEntity<LettersResult> getLetters(@RequestBody LettersRequest request) {
...

Пример проекта здесь .

0 голосов
/ 26 декабря 2018

Вам необходимо:

  • определить два DataSource
  • отметить один из них как @Primary (как вы сделали)
  • определить два LocalContainerEntityManagerFactoryBean em1 и em2 каждый использует разные DataSource
  • определяют два TransactionManagers
  • помещают все репозитории, которые должны использовать первый DataSource, в пакет pkg1 идругие репозитории в пакете pkg2
  • определяют класс @Configuration с @EnableJpaRepositories с basePackages = "pkg1" и entityManagerFactoryRef = "em1"
  • и второй @Configuration класс для pkg2 иem2

Это описано в документации Spring Boot - 84.10 Использование двух EntityManager .

...