2016-05-02 7 views
2

Я пытаюсь создать приложение Spring Boot, которое соединяется с двумя источниками данных. я могу добиться этого, следуя Спринг документацию, но проблема я столкнулся, чтобы достичь следующегоВесенняя загрузка с несколькими источниками данных + JNDI

  • С помощью Spring Загрузочного DataSourceAutoConfiguration создания DataSource оба JNDI Lookup и указания свойств DataSource
  • Переключения между вышеупомянутые два метода на основе активного профиля пружины.

Мой application.yml выглядит

server: 
port: 9001 
contextPath: /ready 
spring: 
datasource: 
    one: 
    url: jdbc:mysql://localhost:3307/dummy 
    driver-class-name: com.mysql.jdbc.Driver 
    username: root 
    password: root 
    two: 
    url: jdbc:mysql://localhost:3307/dummy_two 
    driver-class-name: com.mysql.jdbc.Driver 
    username: root 
    password: root 

--- 
spring: 
profiles: DEV 
spring.datasource: 
one: 
    jndi-name: jdbc/myDBOne 
two: 
    jndi-name: jdbc/myDBTwo 

классы JpaConfig для двух источников данных заключаются в следующем:

  package com.springboot.web.config; 

      import javax.persistence.EntityManagerFactory; 
      import javax.sql.DataSource; 
      import org.springframework.beans.factory.annotation.Autowired; 
      import org.springframework.beans.factory.annotation.Qualifier; 
      import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 
      import org.springframework.boot.context.properties.ConfigurationProperties; 
      import org.springframework.boot.context.properties.EnableConfigurationProperties; 
      import org.springframework.context.annotation.Bean; 
      import org.springframework.context.annotation.Configuration; 
      import org.springframework.context.annotation.Primary; 
      import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 
      import org.springframework.orm.jpa.JpaTransactionManager; 
      import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
      import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; 
      import org.springframework.transaction.PlatformTransactionManager; 
      import org.springframework.transaction.annotation.EnableTransactionManagement; 

      /** 
      * 
      * @author amardeep2551 
      */ 
      @Configuration 

      @EnableTransactionManagement 
      @EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryOne", 
       basePackages = { "com.springboot.web.repo.one" }) 
      public class JpaConfigOne { 





       @Primary 
       @Bean(name = "entityManagerFactoryOne") 
       @ConfigurationProperties(prefix = "spring.datasource.one") 
       public LocalContainerEntityManagerFactoryBean entityManagerFactoryOne(
        DataSource dataSource 
        ) { 

        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean(); 
       lef.setPackagesToScan("com.springboot.web.domain.one"); 
       lef.setDataSource(dataSource); 
       lef.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); 

       return lef; 
       } 

       @Primary 
       @Bean(name = "transactionManager") 
       public PlatformTransactionManager transactionManager(
        @Qualifier("entityManagerFactoryOne") EntityManagerFactory entityManagerFactoryOne) { 
       return new JpaTransactionManager(entityManagerFactoryOne); 
       } 
      } 

      /* 
      * To change this license header, choose License Headers in Project Properties. 
      * To change this template file, choose Tools | Templates 
      * and open the template in the editor. 
      */ 
      package com.springboot.web.config; 

      import javax.persistence.EntityManagerFactory; 
      import javax.sql.DataSource; 
      import org.springframework.beans.factory.annotation.Autowired; 
      import org.springframework.beans.factory.annotation.Qualifier; 
      import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 
      import org.springframework.boot.context.properties.ConfigurationProperties; 
      import org.springframework.context.annotation.Bean; 
      import org.springframework.context.annotation.Configuration; 
      import org.springframework.context.annotation.Primary; 
      import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 
      import org.springframework.orm.jpa.JpaTransactionManager; 
      import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
      import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; 
      import org.springframework.transaction.PlatformTransactionManager; 
      import org.springframework.transaction.annotation.EnableTransactionManagement; 

      /** 
      * 
      * @author amardeep2551 
      */ 
      @Configuration 
      @EnableTransactionManagement 
      @EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryTwo", 
       basePackages = { "com.springboot.web.repo.two" }) 
      public class JpaConfigTwo { 



       @Bean(name = "entityManagerFactoryTwo") 
       @ConfigurationProperties(prefix = "spring.datasource.two") 
       public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        DataSource dataSource 
        ) { 

        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean(); 
       lef.setPackagesToScan("com.springboot.web.domain.two"); 
       lef.setDataSource(dataSource); 
       lef.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); 

       return lef; 
       } 

       @Primary 
       @Bean(name = "transactionManager") 
       public PlatformTransactionManager transactionManager(
        @Qualifier("entityManagerFactoryTwo") EntityManagerFactory entityManagerFactory) { 
       return new JpaTransactionManager(entityManagerFactory); 
       } 
      } 

My Spring загрузки Запуск класса выглядит следующим образом:

  /* 
      * To change this license header, choose License Headers in Project Properties. 
      * To change this template file, choose Tools | Templates 
      * and open the template in the editor. 
      */ 
      package com.springboot.web; 

      import org.springframework.boot.SpringApplication; 
      import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
      import org.springframework.boot.autoconfigure.SpringBootApplication; 
      import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 
      import org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration; 
      import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; 
      import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 
      import org.springframework.boot.context.web.SpringBootServletInitializer; 

      /** 
      * 
      * @author amardeep2551 
      */ 
      @EnableAutoConfiguration 
      @SpringBootApplication() 
      public class Application extends SpringBootServletInitializer{ 
       public static void main(String[] args) { 

       SpringApplication.run(Application.class, args); 
       } 
      } 

и, наконец, мой pom.xml выглядит как

   <?xml version="1.0" encoding="UTF-8"?> 
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
       <modelVersion>4.0.0</modelVersion> 
       <parent> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-starter-parent</artifactId> 
       <version>1.3.1.RELEASE</version> 
       <relativePath /> <!-- lookup parent from repository --> 
       </parent> 

       <groupId>com.springboot.web</groupId> 
       <artifactId>SpringBootWeb</artifactId> 
       <version>1.0-SNAPSHOT</version> 
       <packaging>war</packaging> 

       <name>SpringBootWeb</name> 

       <properties> 
       <java.version>1.8</java.version> 
       <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir> 
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
       </properties> 

       <dependencies> 


       <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
       </dependency> 
       <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-data-jpa</artifactId> 
       </dependency> 
       <dependency> 
        <groupId>org.projectlombok</groupId> 
        <artifactId>lombok</artifactId> 
        <version>1.14.4</version> 
        <scope>provided</scope> 
       </dependency> 
       <dependency> 
        <groupId>mysql</groupId> 
        <artifactId>mysql-connector-java</artifactId> 
       </dependency> 
       <dependency> 
        <groupId>javax</groupId> 
        <artifactId>javaee-web-api</artifactId> 
        <version>6.0</version> 
        <scope>provided</scope> 
       </dependency> 
       </dependencies> 

       <build> 
       <resources> 
        <resource> 
        <directory>src/main/resources</directory> 
        </resource> 
       </resources> 
       <plugins> 

        <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <version>2.3.2</version> 
        <configuration> 
         <source>1.6</source> 
         <target>1.6</target> 
         <compilerArguments> 
         <endorseddirs>${endorsed.dir}</endorseddirs> 
         </compilerArguments> 
        </configuration> 
        </plugin> 
        <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-war-plugin</artifactId> 
        <version>2.1.1</version> 
        <configuration> 
         <failOnMissingWebXml>false</failOnMissingWebXml> 
        </configuration> 
        </plugin> 
        <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-dependency-plugin</artifactId> 
        <version>2.1</version> 
        <executions> 
         <execution> 
         <phase>validate</phase> 
         <goals> 
          <goal>copy</goal> 
         </goals> 
         <configuration> 
          <outputDirectory>${endorsed.dir}</outputDirectory> 
          <silent>true</silent> 
          <artifactItems> 
          <artifactItem> 
           <groupId>javax</groupId> 
           <artifactId>javaee-endorsed-api</artifactId> 
           <version>6.0</version> 
           <type>jar</type> 
          </artifactItem> 
          </artifactItems> 
         </configuration> 
         </execution> 
        </executions> 
        </plugin> 

       </plugins> 
       </build> 
      <repositories> 

       <repository> 
       <id>projectlombok.org</id> 
       <name>Lombok Repository</name> 
       <url>http://projectlombok.org/mavenrepo</url> 
       </repository> 
      </repositories> 
      </project> 

Теперь, когда я запустить основной метод в Application.java я получаю следующее сообщение об ошибке

  org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryOne' defined in class path resource [com/springboot/web/config/JpaConfigOne.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.sql.DataSource]: : Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active). 
       at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:829) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
       at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 
       at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:764) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 
       at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:357) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 
       at org.springframework.boot.SpringApplication.run(SpringApplication.java:305) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 
       at org.springframework.boot.SpringApplication.run(SpringApplication.java:1124) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 
       at org.springframework.boot.SpringApplication.run(SpringApplication.java:1113) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 
       at com.springboot.web.Application.main(Application.java:26) [classes/:na] 

Я понимаю причину ошибки, которая при введении DataSource ниже в методе Spring не в состоянии ассоциировать свойства с префиксом spring.datasource.one и, следовательно, не может определить тип datbase.

@Primary 
@Bean(name = "entityManagerFactoryOne") 
@ConfigurationProperties(prefix = "spring.datasource.one") 
public LocalContainerEntityManagerFactoryBean entityManagerFactoryOne(
     DataSource dataSource 
     ) { 

Есть ли способ достичь этого с помощью Spring загрузки благости AutoConfiguration, или я должен создать различные бобы DataSource на основе профилей.

+0

Я столкнулся с этой идентичной ситуацией. Вы могли сделать эту работу? – bigMC28

+0

Нет, мне пришлось создавать отдельные источники данных для разных профилей. – Amardeep

ответ

0

В моем случае, с использованием файла application.properties.

datasource.one.url=jdbc:mysql://localhost:3306/demo_one 
datasource.one.username=root 
datasource.one.password=root 
datasource.one.driver-class-name=com.mysql.jdbc.Driver 

datasource.two.url=jdbc:mysql://localhost:3306/demo_two 
datasource.two.username=root 
datasource.two.password=root 
datasource.two.driver-class-name=com.mysql.jdbc.Driver 

И затем используется префикс, соответственно, для каждого класса datasource в конфигурации JPA. Не уверен в настройке на основе файла yml.

+0

Спасибо за ваш ответ. То, что вы предложили, я достиг этого в моем нынешнем настроении. То, к чему я стремлюсь, упоминается в последнем разделе моего вопроса. – Amardeep

Смежные вопросы