简体   繁体   中英

Spring Boot Configure and Use Multiple DataSources ( Docker container)

I'm new with Springboot. I try to access multiple database (mysql Docker container) with Springboot and came across with this error.Here is the error:

Description:

Field userRepository in com.example.demo.MainController required a bean named 'UserEntityManagerFactory' that could not be found.

The injection point has the following annotations:
        - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean named 'UserEntityManagerFactory' in your configuration.

I had try some suggestions on google but it not work. For example, fix the pom to

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency> 

or fix the port of database.

Could you guy give me some advice to fix this error?

Here is my code :

User Configure


import com.example.demo.Entity.use.User;
import com.zaxxer.hikari.HikariDataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
@EntityScan()
@EnableJpaRepositories(basePackages = "com.example.demo.Repo.use",
        entityManagerFactoryRef = "UserEntityManagerFactory",
        transactionManagerRef= "UserTransactionManager"
)
public class UserConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.user")
    public DataSourceProperties UserDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.user.configuration")
    public DataSource UserDataSource() {
        return UserDataSourceProperties().initializeDataSourceBuilder()
                .type(HikariDataSource.class).build();
    }

    @Primary
    @Bean(name = "memberEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean UserEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(UserDataSource())
                .packages(User.class)
                .build();
    }

    @Primary
    @Bean
    public PlatformTransactionManager memberTransactionManager(
            final @Qualifier("UserEntityManagerFactory") LocalContainerEntityManagerFactoryBean UserEntityManagerFactory) {
        return new JpaTransactionManager(UserEntityManagerFactory.getObject());
    }

}

Tax Configure


import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

import com.example.demo.Entity.table.Tax;

@Configuration
@EnableJpaRepositories(basePackages = "com.example.demo.Repo.table",
       entityManagerFactoryRef = "TaxEntityManagerFactory",
       transactionManagerRef= "TaxTransactionManager")
public class TaxTableConfiguration {

   @Bean
   @ConfigurationProperties("app.datasource.tax")
   public DataSourceProperties TaxDataSourceProperties() {
       return new DataSourceProperties();
   }

   @Bean
   @ConfigurationProperties("app.datasource.tax.configuration")
   public DataSource TaxDataSource() {
       return TaxDataSourceProperties().initializeDataSourceBuilder()
               .type(BasicDataSource.class).build();
   }

   @Bean(name = "TaxEntityManagerFactory")
   public LocalContainerEntityManagerFactoryBean TaxEntityManagerFactory(
           EntityManagerFactoryBuilder builder) {
       return builder
               .dataSource(TaxDataSource())
               .packages(Tax.class)
               .build();
   }

   @Bean
   public PlatformTransactionManager TaxTransactionManager(
           final @Qualifier("TaxEntityManagerFactory") LocalContainerEntityManagerFactoryBean TaxEntityManagerFactory) {
       return new JpaTransactionManager(TaxEntityManagerFactory.getObject());
   }
}

Controller


import com.example.demo.Entity.use.User;
import com.example.demo.Repo.use.UserRepository;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller // This means that this class is a Controller
@RequestMapping(path="/demo") // This means URL's start with /demo (after Application path)
public class MainController {
  @Autowired // This means to get the bean called userRepository
         // Which is auto-generated by Spring, we will use it to handle the data
  private UserRepository userRepository;

  @PostMapping(path="/add") // Map ONLY POST Requests
  public @ResponseBody String addNewUser (@RequestParam String fname,@RequestParam String lname,
  @RequestParam Integer p_a_salary,@RequestParam Float super_rate,@RequestParam String payment_date ) {
    // @ResponseBody means the returned String is the response, not a view name
    // @RequestParam means it is a parameter from the GET or POST request

    User n = new User();
    n.setlName(lname);
    n.setfName(fname);
    n.set_anual_salary(p_a_salary);
    n.set_super_rate(super_rate);
    n.set_payment_date(payment_date);
    userRepository.save(n);
    return "Saved";
  }

  @GetMapping(path="/all")
  public @ResponseBody Iterable<User> getAllUsers() {
    // This returns a JSON or XML with the users
    return userRepository.findAll();
  }
}

Application

#first  db : 

app.datasource.user.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/taxdb
app.datasource.user.username=user
app.datasource.user.password=password
app.datasource.user.driverClassName=com.mysql.jdbc.Driver

#second db: 
app.datasource.tax.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/calculatedb
app.datasource.tax.username=user
app.datasource.tax.password=password
app.datasource.tax.driverClassName=com.mysql.jdbc.Driver


spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
spring.jpa.database=mysql
server.port = 8080

pom.xml

<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 https://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>2.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
        <commons.dbcp.version>1.4</commons.dbcp.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>${commons.dbcp.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

**User Entity **

package com.example.demo.Entity.use;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity // This tells Hibernate to make a table out of this class
public class User {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id;

  private String fname;

  private String  lname;
  
  private String  payment_date;

  private  Integer  p_a_salary;

  private  Float  super_rate; 
 
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getfName() {
    return fname;
  }

  public void setfName(String fname) {
    this.fname = fname;
  }

  public String getlName() {
    return lname;
  }

  public void setlName(String lname) {
    this.lname = lname;
  }

  public String get_payment_date() {
    return payment_date;
  }

  public void set_payment_date(String payment_date) {
    this.payment_date = payment_date;
  }

  public Integer get_anual_salary() {
    return p_a_salary;
  }

  public void set_anual_salary(Integer p_a_salary) {
    this.p_a_salary = p_a_salary;
  }

  
  public Float get_super_rate() {
    return super_rate;
  }

  public void set_super_rate(Float super_rate) {
    this.super_rate = super_rate;
  }
  
  
}

Tax Entity

package com.example.demo.Entity.table;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity // This tells Hibernate to make a table out of this class
public class Tax {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id;

  private String  taxable_income;

  private Double  addition_charge;
  
  private Double  charge_every_one_dollar;

  
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String get_TaxableIncome() {
    return taxable_income;
  }

  public void set_TaxableIncome(String taxable_income) {
    this.taxable_income = taxable_income;
  }

  public Double get_addition_charge() {
    return addition_charge;
  }

  public void set_additonal_charge(Double addition_charge) {
    this.addition_charge = addition_charge;
  }

  public Double get_charge_every_one_dollar() {
    return charge_every_one_dollar;
  }

  public void set_charge_every_one_dollar(Double charge_every_one_dollar) {
    this.charge_every_one_dollar = charge_every_one_dollar;
  }


  
}

User repository

package com.example.demo.Repo.use;

import com.example.demo.Entity.use.User;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

}

Tax Repository


 

import com.example.demo.Entity.table.Tax;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface taxtableRepository extends JpaRepository<Tax ,Integer> {

}

 

Looks like you should change @Bean(name = "memberEntityManagerFactory") to @Bean(name = "UserEntityManagerFactory") in UserConfiguration.java , because you use UserEntityManagerFactory as a bean name in all other places.

@EnableJpaRepositories(basePackages = "com.example.demo.Repo.use",
        entityManagerFactoryRef = "UserEntityManagerFactory",
        transactionManagerRef= "UserTransactionManager"
)

There are some misconfiguration above annotation. UserEntityManagerFactory and UserTransactionManager do not exists

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM