programing

Spring Data JPA - 여러 EnableJpa 저장소

padding 2023. 8. 16. 22:01
반응형

Spring Data JPA - 여러 EnableJpa 저장소

내 애플리케이션에는 여러 데이터 소스가 있으므로 이 URL을 기반으로 두 개의 데이터 소스 구성 클래스를 만들었습니다.

그러나 스프링 부트 애플리케이션을 실행하는 동안 오류가 발생합니다.

설명:com.cavion의 필드 userDataRepo.서비스UserDataService를 찾을 수 없는 'entityManagerFactory'라는 이름의 빈이 필요합니다.작업:구성에서 'entityManagerFactory'라는 이름의 빈을 정의합니다.

StackOverflow에 대한 질문을 통해 문제를 파악하는 데 도움이 되었습니다. JPA 저장소에서 entityManagerFactoryRef를 지정해야 합니다.

하지만 저는 많은 리포지토리 클래스를 가지고 있습니다. 그 중 일부는 엔티티 관리자 'A'를 사용하고 일부는 'B'를 사용합니다. 현재 제 스프링 부트 애플리케이션 클래스는 다음과 같습니다.

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
    DataSourceTransactionManagerAutoConfiguration.class })
@EnableTransactionManagement
@EntityScan("com.info.entity")
@ComponentScan({"com.info.services","com.info.restcontroller"})
@EnableJpaRepositories("com.info.repositories")
public class CavionApplication {

public static void main(String[] args) {
    SpringApplication.run(CavionApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}}

스프링 부트 클래스에서 EnableJpaResposities를 지정했는데, 여러 EnableJpaResposities를 구성하여 여러 entityManagerFactory를 구성하려면 어떻게 해야 합니까?

여러 데이터 소스를 설정하는 가장 좋은 방법을 제안하십시오.

이 무엇을 이봄무알하기위해게엇을▁knows해▁in위▁what▁spring기.DataSource?Repository 정합야니다에서 .@EnableJpaRepositories주석두 두 개의 우리가있가정다자하고가지고체실개를의,,Servers 및 실와그체Domains엔티티와 각 리포지토리에는 고유한 Repo가 있고 각 리포지토리에는 고유한 JpaDataSource 구성이 있습니다.

관련된 데이터 원본을 기준으로 모든 리포지토리를 그룹화합니다.예를들면

저소에 대한 :Domains 엔티패지(키티):org.springdemo.multiple.datasources.repository.domains):

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> {
}

저소에 대한 :Servers 엔티패지(키티):org.springdemo.multiple.datasources.repository.servers)

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

import org.springdemo.multiple.datasources.domain.servers.Servers;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ServersRepository extends JpaRepository<Servers,Long> {
}

각 JPA 데이터 소스에 대해 구성을 정의해야 합니다. 이 예에서는 두 개의 서로 다른 데이터 소스를 구성하는 방법을 보여 줍니다.

Domains Configuration:는 Jpa 구성소저간장관의다정있의에서 됩니다.basePackages값. 즉, 각 repo가 사용할 엔티티 관리자에 따라 서로 다른 패키지로 리포지토리를 그룹화해야 하는 이유입니다.

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "domainsEntityManager",
        transactionManagerRef = "domainsTransactionManager",
        basePackages = {"org.springdemo.multiple.datasources.repository.domains"}
        )
public class DomainsConfig {

Servers 보시는 은 다음과 같습니다. basePackages는 다음과 같습니다.Servers 및의 값entityManagerFactoryRef그리고.transactionManagerRef스프링이 각 엔터티를 분리하도록 하기 위해 다릅니다.매니저님.

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "serversEntityManager",
        transactionManagerRef = "serversTransactionManager",
        basePackages = {"org.springdemo.multiple.datasources.repository.servers"}
        )
public class ServersConfig {

하나의 데이터 소스를 기본으로 설정

오류 메시지를 방지하려면 다음을 수행합니다.Parameter 0 of constructor in org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration required a single bean, but 2 were found:데이터 소스 중 하나를 @Primary로 설정하면 됩니다. 이 예에서는Servers기본 데이터 소스:

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



@Bean("serversDataSource")
@Primary
@ConfigurationProperties("app.datasource.servers")
public DataSource serversDataSource(@Qualifier("serversDataSourceProperties") DataSourceProperties serversDataSourceProperties) {
    return serversDataSourceProperties().initializeDataSourceBuilder().build();
}

자세한 내용은 각 구성의 전체 예를 참조하십시오.

ServersJPA 구성

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "serversEntityManager",
        transactionManagerRef = "serversTransactionManager",
        basePackages = {"org.springdemo.multiple.datasources.repository.servers"}
        )
public class ServersConfig {

    @Bean(name = "serversEntityManager")
    public LocalContainerEntityManagerFactoryBean getServersEntityManager(EntityManagerFactoryBuilder builder,
                                                                          @Qualifier("serversDataSource") DataSource serversDataSource){


        return builder
                .dataSource(serversDataSource)
                .packages("org.springdemo.multiple.datasources.domain.servers")
                .persistenceUnit("servers")
                .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.MySQLDialect");
        map.put("hibernate.show_sql", "true");

        return map;
    }


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



    @Bean("serversDataSource")
    @Primary
    @ConfigurationProperties("app.datasource.servers")
    public DataSource serversDataSource(@Qualifier("serversDataSourceProperties") DataSourceProperties serversDataSourceProperties) {
        return serversDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean(name = "serversTransactionManager")
    public JpaTransactionManager transactionManager(@Qualifier("serversEntityManager") EntityManagerFactory serversEntityManager){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(serversEntityManager);

        return transactionManager;
    }
}

DomainsJPA 구성

@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;
    }

}

각 데이터 소스를 분리하기 위해 구성을 다음에 추가했습니다.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&useSSL=false
app.datasource.servers.username=myuser
app.datasource.servers.password=mypass

자세한 내용은 다음 설명서를 참조하십시오.

Spring Documentation: 2가지 데이터 소스 사용 방법

두 개의 서로 다른 데이터베이스를 구성하는 방법에 대한 유사한 예: github 예제

@Daniel C.가 제공한 답변은 정확합니다.내 쪽에서 보는 작은 수정/관찰.

  • @데이터 원본을 기본값으로 표시하지 않으려면 기본값이 필요하지 않습니다. 그렇지 않으면 필요합니다.
  • EntityManagerFactoryBean entityManagerFactory로 정의하는 경우 충돌을 방지하려면 @Primary로 표시하는 것이 좋습니다.
  • @구성 속성("app.data source").서버")를 메서드 수준에서 정의하는 대신 클래스 수준에서 표시할 수 있습니다.
  • Spring Boot 2.x 이상 버전을 변경하여 사용하는 경우 HikariDataSource를 데이터 소스로 반환하는 것이 좋습니다.
  • HikariDataSource에서 JDBC 연결 URL을 참조하는 데 사용하는 jdbc-url에 대해 정확한 속성을 정의해야 합니다.

방금 mysqling github에 대한 모듈 인식 다중 데이터베이스 인식 라이브러리를 추가했습니다.일부 응용 프로그램 속성을 추가해야 합니다.

설명서 및 기타 세부 정보는 다음 사이트에서 확인할 수 있습니다.

https://github.com/yatharthamishra0419/spring-boot-data-multimodule-mysql

언급URL : https://stackoverflow.com/questions/45663025/spring-data-jpa-multiple-enablejparepositories

반응형