admin管理员组

文章数量:1130349

Project Structure

com.example.multidb
├── mysql
│   ├── entity
│   ├── repository
│   └── config
├── postgres
│   ├── entity
│   ├── repository
│   └── config
└── mongodb
    ├── document
    ├── repository
    └── config

Maven (pom.xml):

<dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- PostgreSQL Driver -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.6.0</version>
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.34</version>
    </dependency>

    <!-- Spring Boot Starter Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <!-- Other necessary dependencies -->
    <!-- ... -->
</dependencies>

Setting up Configuration Classes

Set up separate configuration classes for each relational database (PostgreSQL and MySQL) and MongoDB.

PostgreSQL Configuration

Create a configuration class for PostgreSQL in com.example.multidb.postgres.config. package com.example.multidb.postgres.config;


import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.postgres.repository",
    entityManagerFactoryRef = "postgresEntityManagerFactory",
    transactionManagerRef = "postgresTransactionManager"
)
@EntityScan("com.example.multidb.postgres.entity")
public class PostgresConfig {

    @Bean(name = "postgresDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.postgres")
    public DataSource postgresDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "postgresEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("postgresDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.postgres.entity")
                .persistenceUnit("postgres")
                .build();
    }

    @Bean(name = "postgresTransactionManager")
    public PlatformTransactionManager postgresTransactionManager(
            @Qualifier("postgresEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MySQL Configuration

Create a configuration class for MySQL in com.example.multidb.mysql.config.


package com.example.multidb.mysql.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.mysql.repository",
    entityManagerFactoryRef = "mysqlEntityManagerFactory",
    transactionManagerRef = "mysqlTransactionManager"
)
@EntityScan("com.example.multidb.mysql.entity")
public class MySQLConfig {

    @Bean(name = "mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mysqlEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("mysqlDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.mysql.entity")
                .persistenceUnit("mysql")
                .build();
    }

    @Bean(name = "mysqlTransactionManager")
    public PlatformTransactionManager mysqlTransactionManager(
            @Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MongoDB Configuration

For MongoDB, Spring Data MongoDB provides auto-configuration. However, if you need custom configurations, you can define them. Create a configuration class in com.example.multidb.mongodb.config.

package com.example.multidb.mongodb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(
    basePackages = "com.example.multidb.mongodb.repository",
    mongoTemplateRef = "mongoTemplate"
)
public class MongoConfig {
    // Default configurations are usually sufficient.
    // Customize if necessary.
}

Define Entity and Document Classes

Create entity classes for PostgreSQL and MySQL, and document classes for MongoDB.

PostgreSQL Entity

package com.example.multidb.postgres.entity;

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

@Entity
@Table(name = "postgres_entities")
public class PostgresEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    // Other fields, getters, setters
}

MySQL Entity

package com.example.multidb.mysql.entity;

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

@Entity
@Table(name = "mysql_entities")
public class MySQLEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String description;
    // Other fields, getters, setters
}

MongoDB

package com.example.multidb.mongodb.document;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "mongodb_documents")
public class MongoDocument {

    @Id
    private String id;

    private String title;
    // Other fields, getters, setters
}

Create Repository Interfaces

Define repository interfaces for each database type within their respective packages.

PostgreSQL

package com.example.multidb.postgres.repository;

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

import com.example.multidb.postgres.entity.PostgresEntity;

@Repository
public interface PostgresEntityRepository extends JpaRepository<PostgresEntity, Long> {
    // Define query methods if needed
}

MySQL Repository

package com.example.multidb.mysql.repository;

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

import com.example.multidb.mysql.entity.MySQLEntity;

@Repository
public interface MySQLEntityRepository extends JpaRepository<MySQLEntity, Long> {
    // Define query methods if needed
}

MongoDB

package com.example.multidb.mongodb.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.example.multidb.mongodb.document.MongoDocument;

@Repository
public interface MongoDocumentRepository extends MongoRepository<MongoDocument, String> {
    // Define query methods if needed
}

Error

Consider defining a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' in your configuration.

Description:

Parameter 0 of method mysqlEntityManagerFactory in com.example.multidb.mysql.config.MySQLConfig required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.

Project Structure

com.example.multidb
├── mysql
│   ├── entity
│   ├── repository
│   └── config
├── postgres
│   ├── entity
│   ├── repository
│   └── config
└── mongodb
    ├── document
    ├── repository
    └── config

Maven (pom.xml):

<dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- PostgreSQL Driver -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.6.0</version>
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.34</version>
    </dependency>

    <!-- Spring Boot Starter Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <!-- Other necessary dependencies -->
    <!-- ... -->
</dependencies>

Setting up Configuration Classes

Set up separate configuration classes for each relational database (PostgreSQL and MySQL) and MongoDB.

PostgreSQL Configuration

Create a configuration class for PostgreSQL in com.example.multidb.postgres.config. package com.example.multidb.postgres.config;


import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.postgres.repository",
    entityManagerFactoryRef = "postgresEntityManagerFactory",
    transactionManagerRef = "postgresTransactionManager"
)
@EntityScan("com.example.multidb.postgres.entity")
public class PostgresConfig {

    @Bean(name = "postgresDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.postgres")
    public DataSource postgresDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "postgresEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("postgresDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.postgres.entity")
                .persistenceUnit("postgres")
                .build();
    }

    @Bean(name = "postgresTransactionManager")
    public PlatformTransactionManager postgresTransactionManager(
            @Qualifier("postgresEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MySQL Configuration

Create a configuration class for MySQL in com.example.multidb.mysql.config.


package com.example.multidb.mysql.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.mysql.repository",
    entityManagerFactoryRef = "mysqlEntityManagerFactory",
    transactionManagerRef = "mysqlTransactionManager"
)
@EntityScan("com.example.multidb.mysql.entity")
public class MySQLConfig {

    @Bean(name = "mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mysqlEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("mysqlDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.mysql.entity")
                .persistenceUnit("mysql")
                .build();
    }

    @Bean(name = "mysqlTransactionManager")
    public PlatformTransactionManager mysqlTransactionManager(
            @Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MongoDB Configuration

For MongoDB, Spring Data MongoDB provides auto-configuration. However, if you need custom configurations, you can define them. Create a configuration class in com.example.multidb.mongodb.config.

package com.example.multidb.mongodb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(
    basePackages = "com.example.multidb.mongodb.repository",
    mongoTemplateRef = "mongoTemplate"
)
public class MongoConfig {
    // Default configurations are usually sufficient.
    // Customize if necessary.
}

Define Entity and Document Classes

Create entity classes for PostgreSQL and MySQL, and document classes for MongoDB.

PostgreSQL Entity

package com.example.multidb.postgres.entity;

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

@Entity
@Table(name = "postgres_entities")
public class PostgresEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    // Other fields, getters, setters
}

MySQL Entity

package com.example.multidb.mysql.entity;

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

@Entity
@Table(name = "mysql_entities")
public class MySQLEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String description;
    // Other fields, getters, setters
}

MongoDB

package com.example.multidb.mongodb.document;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "mongodb_documents")
public class MongoDocument {

    @Id
    private String id;

    private String title;
    // Other fields, getters, setters
}

Create Repository Interfaces

Define repository interfaces for each database type within their respective packages.

PostgreSQL

package com.example.multidb.postgres.repository;

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

import com.example.multidb.postgres.entity.PostgresEntity;

@Repository
public interface PostgresEntityRepository extends JpaRepository<PostgresEntity, Long> {
    // Define query methods if needed
}

MySQL Repository

package com.example.multidb.mysql.repository;

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

import com.example.multidb.mysql.entity.MySQLEntity;

@Repository
public interface MySQLEntityRepository extends JpaRepository<MySQLEntity, Long> {
    // Define query methods if needed
}

MongoDB

package com.example.multidb.mongodb.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.example.multidb.mongodb.document.MongoDocument;

@Repository
public interface MongoDocumentRepository extends MongoRepository<MongoDocument, String> {
    // Define query methods if needed
}

Error

Consider defining a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' in your configuration.

Description:

Parameter 0 of method mysqlEntityManagerFactory in com.example.multidb.mysql.config.MySQLConfig required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.

Share Improve this question edited 2 days ago Shadow 34.2k10 gold badges62 silver badges72 bronze badges asked 2 days ago SHIVAM SINGHSHIVAM SINGH 14 bronze badges 2
  • Wellyour question is not really clear; I mean... when do you want to use MySQL instead of PostgreSQL or MongoDB? And, in the postgreSQL and mySQL case, why to split entities and repositories? wouldn't they be always the same? In any case, on relational DB side you can use the RoutingDatabase concept provided by spring (spring.io/blog/2007/01/23/dynamic-datasource-routing); in this case by using a custom logic (e.g. a custom HTTP header in requests) you can switch from MySQL to PostgreSQL and viceversa. With mongo you can try to extend the datasource routing concept but I never tried it – Angelo Immediata Commented 2 days ago
  • I want to Set Up and Manage Multiple Databases in Spring Boot – SHIVAM SINGH Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 0

EntityManagerFactoryBuilder is a bean provided by org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration which kick in only by org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration

@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {

Notice the @ConditionalOnSingleCandidate(DataSource.class), in your case, it is not truthy, hence the exception bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found

I see 2 options:

  • You mark one of your Datasource with @Primay as @ConditionalOnSingleCandidate stipulate "The condition will also match if multiple matching bean instances are already contained in the BeanFactory but a primary candidate has been defined; essentially, the condition match if auto-wiring"
  • You create an instance of the builder for each datasource with a specific qualifier (like you did for the rest of the beans)

Then it should works just as expected

Project Structure

com.example.multidb
├── mysql
│   ├── entity
│   ├── repository
│   └── config
├── postgres
│   ├── entity
│   ├── repository
│   └── config
└── mongodb
    ├── document
    ├── repository
    └── config

Maven (pom.xml):

<dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- PostgreSQL Driver -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.6.0</version>
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.34</version>
    </dependency>

    <!-- Spring Boot Starter Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <!-- Other necessary dependencies -->
    <!-- ... -->
</dependencies>

Setting up Configuration Classes

Set up separate configuration classes for each relational database (PostgreSQL and MySQL) and MongoDB.

PostgreSQL Configuration

Create a configuration class for PostgreSQL in com.example.multidb.postgres.config. package com.example.multidb.postgres.config;


import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.postgres.repository",
    entityManagerFactoryRef = "postgresEntityManagerFactory",
    transactionManagerRef = "postgresTransactionManager"
)
@EntityScan("com.example.multidb.postgres.entity")
public class PostgresConfig {

    @Bean(name = "postgresDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.postgres")
    public DataSource postgresDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "postgresEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("postgresDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.postgres.entity")
                .persistenceUnit("postgres")
                .build();
    }

    @Bean(name = "postgresTransactionManager")
    public PlatformTransactionManager postgresTransactionManager(
            @Qualifier("postgresEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MySQL Configuration

Create a configuration class for MySQL in com.example.multidb.mysql.config.


package com.example.multidb.mysql.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.mysql.repository",
    entityManagerFactoryRef = "mysqlEntityManagerFactory",
    transactionManagerRef = "mysqlTransactionManager"
)
@EntityScan("com.example.multidb.mysql.entity")
public class MySQLConfig {

    @Bean(name = "mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mysqlEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("mysqlDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.mysql.entity")
                .persistenceUnit("mysql")
                .build();
    }

    @Bean(name = "mysqlTransactionManager")
    public PlatformTransactionManager mysqlTransactionManager(
            @Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MongoDB Configuration

For MongoDB, Spring Data MongoDB provides auto-configuration. However, if you need custom configurations, you can define them. Create a configuration class in com.example.multidb.mongodb.config.

package com.example.multidb.mongodb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(
    basePackages = "com.example.multidb.mongodb.repository",
    mongoTemplateRef = "mongoTemplate"
)
public class MongoConfig {
    // Default configurations are usually sufficient.
    // Customize if necessary.
}

Define Entity and Document Classes

Create entity classes for PostgreSQL and MySQL, and document classes for MongoDB.

PostgreSQL Entity

package com.example.multidb.postgres.entity;

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

@Entity
@Table(name = "postgres_entities")
public class PostgresEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    // Other fields, getters, setters
}

MySQL Entity

package com.example.multidb.mysql.entity;

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

@Entity
@Table(name = "mysql_entities")
public class MySQLEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String description;
    // Other fields, getters, setters
}

MongoDB

package com.example.multidb.mongodb.document;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "mongodb_documents")
public class MongoDocument {

    @Id
    private String id;

    private String title;
    // Other fields, getters, setters
}

Create Repository Interfaces

Define repository interfaces for each database type within their respective packages.

PostgreSQL

package com.example.multidb.postgres.repository;

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

import com.example.multidb.postgres.entity.PostgresEntity;

@Repository
public interface PostgresEntityRepository extends JpaRepository<PostgresEntity, Long> {
    // Define query methods if needed
}

MySQL Repository

package com.example.multidb.mysql.repository;

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

import com.example.multidb.mysql.entity.MySQLEntity;

@Repository
public interface MySQLEntityRepository extends JpaRepository<MySQLEntity, Long> {
    // Define query methods if needed
}

MongoDB

package com.example.multidb.mongodb.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.example.multidb.mongodb.document.MongoDocument;

@Repository
public interface MongoDocumentRepository extends MongoRepository<MongoDocument, String> {
    // Define query methods if needed
}

Error

Consider defining a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' in your configuration.

Description:

Parameter 0 of method mysqlEntityManagerFactory in com.example.multidb.mysql.config.MySQLConfig required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.

Project Structure

com.example.multidb
├── mysql
│   ├── entity
│   ├── repository
│   └── config
├── postgres
│   ├── entity
│   ├── repository
│   └── config
└── mongodb
    ├── document
    ├── repository
    └── config

Maven (pom.xml):

<dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- PostgreSQL Driver -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.6.0</version>
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.34</version>
    </dependency>

    <!-- Spring Boot Starter Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <!-- Other necessary dependencies -->
    <!-- ... -->
</dependencies>

Setting up Configuration Classes

Set up separate configuration classes for each relational database (PostgreSQL and MySQL) and MongoDB.

PostgreSQL Configuration

Create a configuration class for PostgreSQL in com.example.multidb.postgres.config. package com.example.multidb.postgres.config;


import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.postgres.repository",
    entityManagerFactoryRef = "postgresEntityManagerFactory",
    transactionManagerRef = "postgresTransactionManager"
)
@EntityScan("com.example.multidb.postgres.entity")
public class PostgresConfig {

    @Bean(name = "postgresDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.postgres")
    public DataSource postgresDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "postgresEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("postgresDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.postgres.entity")
                .persistenceUnit("postgres")
                .build();
    }

    @Bean(name = "postgresTransactionManager")
    public PlatformTransactionManager postgresTransactionManager(
            @Qualifier("postgresEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MySQL Configuration

Create a configuration class for MySQL in com.example.multidb.mysql.config.


package com.example.multidb.mysql.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.multidb.mysql.repository",
    entityManagerFactoryRef = "mysqlEntityManagerFactory",
    transactionManagerRef = "mysqlTransactionManager"
)
@EntityScan("com.example.multidb.mysql.entity")
public class MySQLConfig {

    @Bean(name = "mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mysqlEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("mysqlDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.multidb.mysql.entity")
                .persistenceUnit("mysql")
                .build();
    }

    @Bean(name = "mysqlTransactionManager")
    public PlatformTransactionManager mysqlTransactionManager(
            @Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

MongoDB Configuration

For MongoDB, Spring Data MongoDB provides auto-configuration. However, if you need custom configurations, you can define them. Create a configuration class in com.example.multidb.mongodb.config.

package com.example.multidb.mongodb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(
    basePackages = "com.example.multidb.mongodb.repository",
    mongoTemplateRef = "mongoTemplate"
)
public class MongoConfig {
    // Default configurations are usually sufficient.
    // Customize if necessary.
}

Define Entity and Document Classes

Create entity classes for PostgreSQL and MySQL, and document classes for MongoDB.

PostgreSQL Entity

package com.example.multidb.postgres.entity;

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

@Entity
@Table(name = "postgres_entities")
public class PostgresEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    // Other fields, getters, setters
}

MySQL Entity

package com.example.multidb.mysql.entity;

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

@Entity
@Table(name = "mysql_entities")
public class MySQLEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String description;
    // Other fields, getters, setters
}

MongoDB

package com.example.multidb.mongodb.document;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "mongodb_documents")
public class MongoDocument {

    @Id
    private String id;

    private String title;
    // Other fields, getters, setters
}

Create Repository Interfaces

Define repository interfaces for each database type within their respective packages.

PostgreSQL

package com.example.multidb.postgres.repository;

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

import com.example.multidb.postgres.entity.PostgresEntity;

@Repository
public interface PostgresEntityRepository extends JpaRepository<PostgresEntity, Long> {
    // Define query methods if needed
}

MySQL Repository

package com.example.multidb.mysql.repository;

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

import com.example.multidb.mysql.entity.MySQLEntity;

@Repository
public interface MySQLEntityRepository extends JpaRepository<MySQLEntity, Long> {
    // Define query methods if needed
}

MongoDB

package com.example.multidb.mongodb.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.example.multidb.mongodb.document.MongoDocument;

@Repository
public interface MongoDocumentRepository extends MongoRepository<MongoDocument, String> {
    // Define query methods if needed
}

Error

Consider defining a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' in your configuration.

Description:

Parameter 0 of method mysqlEntityManagerFactory in com.example.multidb.mysql.config.MySQLConfig required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.

Share Improve this question edited 2 days ago Shadow 34.2k10 gold badges62 silver badges72 bronze badges asked 2 days ago SHIVAM SINGHSHIVAM SINGH 14 bronze badges 2
  • Wellyour question is not really clear; I mean... when do you want to use MySQL instead of PostgreSQL or MongoDB? And, in the postgreSQL and mySQL case, why to split entities and repositories? wouldn't they be always the same? In any case, on relational DB side you can use the RoutingDatabase concept provided by spring (spring.io/blog/2007/01/23/dynamic-datasource-routing); in this case by using a custom logic (e.g. a custom HTTP header in requests) you can switch from MySQL to PostgreSQL and viceversa. With mongo you can try to extend the datasource routing concept but I never tried it – Angelo Immediata Commented 2 days ago
  • I want to Set Up and Manage Multiple Databases in Spring Boot – SHIVAM SINGH Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 0

EntityManagerFactoryBuilder is a bean provided by org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration which kick in only by org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration

@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {

Notice the @ConditionalOnSingleCandidate(DataSource.class), in your case, it is not truthy, hence the exception bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found

I see 2 options:

  • You mark one of your Datasource with @Primay as @ConditionalOnSingleCandidate stipulate "The condition will also match if multiple matching bean instances are already contained in the BeanFactory but a primary candidate has been defined; essentially, the condition match if auto-wiring"
  • You create an instance of the builder for each datasource with a specific qualifier (like you did for the rest of the beans)

Then it should works just as expected

本文标签: