[SPRING] Spring 데이터 JPA - 다중 EnableJpaRepositories
SPRINGSpring 데이터 JPA - 다중 EnableJpaRepositories
내 응용 프로그램에는 여러 데이터 소스가 있으므로이 URL을 기반으로 두 가지 데이터 소스 구성 클래스를 만들었습니다.
그러나 봄 부팅 응용 프로그램을 실행하는 동안 오류가 발생합니다.
이 StackOverflow에 대한 질문에서 문제점을 파악하는 데 도움이되었습니다. JPA 저장소에서 entityManagerFactoryRef를 지정해야합니다.
하지만 나는 많은 저장소 클래스를 가지고 있는데, 그들 중 일부는 Entitymanager '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);
}
};
}}
Spring 부트 클래스에서 EnableJpaRepositories를주었습니다. 그래서 어떻게 여러 개의 EnableManagerpage를 구성하여 여러 개의 entityManagerFactory를 구성 할 수 있습니까?
여러 데이터 소스를 설정하는 가장 좋은 방법을 제안하십시오.
해결법
-
==============================
1.Spring이 어떤 DataSource가 어떤 저장소와 관련되어 있는지를 알 수 있도록 @EnableJpaRepositories 주석에서 정의해야한다. 서버 엔티티와 도메인 엔티티의 두 엔티티가 있고 각 엔티티에는 자체 Repo가 있고 각 리포지토리에 자체 JpaDataSource 구성이 있다고 가정 해 봅니다.
Spring이 어떤 DataSource가 어떤 저장소와 관련되어 있는지를 알 수 있도록 @EnableJpaRepositories 주석에서 정의해야한다. 서버 엔티티와 도메인 엔티티의 두 엔티티가 있고 각 엔티티에는 자체 Repo가 있고 각 리포지토리에 자체 JpaDataSource 구성이 있다고 가정 해 봅니다.
1. 관련된 모든 데이터 소스를 기반으로 모든 리포지토리를 그룹화합니다. 예를 들어
도메인 엔티티 저장소 (package : 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> { }
서버 저장소 용 엔티티 (패키지 : 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> { }
2. 각 JPA 데이터 소스에 대해 구성을 정의해야합니다.이 예에서는 두 개의 다른 데이터 소스를 구성하는 방법을 보여줍니다
도메인 Jpa 구성 : 데이터 소스와 저장소 간의 관계가 basePackages 값에 정의됩니다. 즉, 각 저장소가 사용할 엔터티 관리자에 따라 저장소를 여러 패키지로 그룹화해야하는 이유입니다.
@Configuration @EnableJpaRepositories( entityManagerFactoryRef = "domainsEntityManager", transactionManagerRef = "domainsTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.domains"} ) public class DomainsConfig {
서버 데이터 소스 설정 : basePackages 값은 Servers Repository의 패키지 이름을 가지며, entityManagerFactoryRef와 transactionManagerRef의 값은 Spring이 각 entityManager를 분리하도록하기 위해 서로 다릅니다.
@Configuration @EnableJpaRepositories( entityManagerFactoryRef = "serversEntityManager", transactionManagerRef = "serversTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.servers"} ) public class ServersConfig {
3. 하나의 데이터 소스를 기본 데이터로 설정하십시오.
에러 메시지를 피하기 위해서 : org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration에있는 생성자의 파라미터 0은 하나의 빈을 요구했지만 2 개가 발견되었습니다 : 데이터 소스 중 하나를 @Primary로 설정합니다,이 예제에서는 서버 데이터 소스를 기본으로 선택하십시오.
@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(); }
자세한 정보가 필요하면 각 구성에 대한 전체 예제를 참조하십시오.
서버 JPA 구성
@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; } }
도메인 JPA 구성
@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 문서 : howto-two-datasources
두 개의 서로 다른 데이터베이스를 구성하는 방법과 비슷한 예 : github 예제
from https://stackoverflow.com/questions/45663025/spring-data-jpa-multiple-enablejparepositories by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 싱글 톤 스레드 안전성 (0) | 2019.01.12 |
---|---|
[SPRING] sessionFactory.getCurrentSession ()에 대한 최대 절전 모드 필터를 설정하는 방법은 무엇입니까? (0) | 2019.01.12 |
[SPRING] 스프링 3.1에서 기본 인증을 사용하여 RestTemplate (0) | 2019.01.12 |
[SPRING] Spring MVC : 귀속 컨텍스트 공유 (0) | 2019.01.11 |
[SPRING] 여러 데이터 소스를 사용하는 Hibernate + Spring? (0) | 2019.01.11 |