A Guide to Configuring Multiple Data Source JPA Repositories in Spring Boot

Dec 06, 2025 · Programming · 8 views · 7.8

Keywords: Spring Boot | Multiple Data Sources | JPA Repositories | @EnableJpaRepositories

Abstract: This article provides a detailed guide on configuring multiple data sources and associating different JPA repositories in a Spring Boot application. By grouping repository packages, defining independent configuration classes, setting a primary data source, and configuring property files, it addresses common errors like missing entityManagerFactory, with code examples and best practices.

Introduction

In Spring Boot applications, configuring JPA repositories with multiple data sources can present challenges, such as common errors: Field userDataRepo in com.cavion.services.UserDataService required a bean named 'entityManagerFactory' that could not be found. Based on best practices, this article offers a comprehensive solution to efficiently manage multi-data-source environments.

Core Solution

To correctly configure JPA repositories across multiple data sources, follow these steps: group repositories into different packages based on data sources; create independent configuration classes for each data source, using the @EnableJpaRepositories annotation to specify entityManagerFactoryRef, transactionManagerRef, and basePackages; set one data source as @Primary to avoid auto-configuration conflicts; define properties for each data source in the application.properties file.

Detailed Configuration Example

Assume an application has two entities: Domains and Servers, each corresponding to a different data source. First, group the repositories:

package org.springdemo.multiple.datasources.repository.domains;

import org.springdemo.multiple.datasources.domain.domains.Domains;
import org.springframework.data.jpa.repository.JpaRepository;

public interface DomainsRepository extends JpaRepository<Domains,Long> {
}

Similarly, create a repository package for Servers. Next, configure the data sources. Using Domains data source as an example:

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "domainsEntityManager",
        transactionManagerRef = "domainsTransactionManager",
        basePackages = {"org.springdemo.multiple.datasources.repository.domains"}
        )
public class DomainsConfig {
    @Bean(name = "domainsEntityManager")
    public LocalContainerEntityManagerFactoryBean getDomainsEntityManager(EntityManagerFactoryBuilder builder,
                                                                          @Qualifier("domainsDataSource") DataSource domainsDataSource){
        return builder
                .dataSource(domainsDataSource)
                .packages("org.springdemo.multiple.datasources.domain.domains")
                .persistenceUnit("domains")
                .properties(additionalJpaProperties())
                .build();
    }

    Map<String,?> additionalJpaProperties(){
        Map<String,String> map = new HashMap<>();
        map.put("hibernate.hbm2ddl.auto", "create");
        map.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        map.put("hibernate.show_sql", "true");
        return map;
    }

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

    @Bean("domainsDataSource")
    public DataSource domainsDataSource(@Qualifier("domainsDataSourceProperties") DataSourceProperties domainsDataSourceProperties) {
        return domainsDataSourceProperties.initializeDataSourceBuilder().build();
    }

    @Bean(name = "domainsTransactionManager")
    public JpaTransactionManager transactionManager(@Qualifier("domainsEntityManager") EntityManagerFactory domainsEntityManager){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(domainsEntityManager);
        return transactionManager;
    }
}

For the Servers data source, configure similarly but with different packages and properties, and set as @Primary to prevent conflicts. Define properties in application.properties:

app.datasource.domains.url=jdbc:h2:mem:~/test
app.datasource.domains.driver-class-name=org.h2.Driver

app.datasource.servers.driver-class-name=com.mysql.jdbc.Driver
app.datasource.servers.url=jdbc:mysql://localhost:3306/v?autoReconnect=true&amp;useSSL=false
app.datasource.servers.username=myuser
app.datasource.servers.password=mypass

Note: In URLs, the & character must be escaped as &amp; to avoid HTML parsing errors.

Conclusion

By grouping repositories, defining configuration classes, and setting a primary data source, you can effectively manage multiple data source JPA repositories in Spring Boot, avoiding common configuration issues. This approach offers flexibility and maintainability for complex enterprise applications.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.