복붙노트

[SPRING] 여러 jpa : xml config의 저장소, Spring java config를 사용하여 @EnableJPARepositories를 구성하는 방법은 무엇입니까?

SPRING

여러 jpa : xml config의 저장소, Spring java config를 사용하여 @EnableJPARepositories를 구성하는 방법은 무엇입니까?

나는 스프링 데이터 jpa를 다중 datasources와 함께 사용하는 방법에 대한 설명과 샘플 코드를 연구하고 발견했다.이 코드는 다음과 같이 xml 구성에 여러 jpa : repositories를 구성하는 것을 참조한다.

<jpa:repositories base-package="org.springframework.data.jpa.repository.sample"
    entity-manager-factory-ref="entityManagerFactory">
    <repository:exclude-filter type="assignable" expression="org.springframework.data.jpa.repository.sample.AuditableUserRepository" />
</jpa:repositories>
<jpa:repositories base-package="org.springframework.data.jpa.repository.sample"
    entity-manager-factory-ref="entityManagerFactory-2"
    transaction-manager-ref="transactionManager-2">
    <repository:include-filter type="assignable" expression="org.springframework.data.jpa.repository.sample.AuditableUserRepository" />
</jpa:repositories>

위의 jpa : 자바 설정과 @EnableJpaRepositories 주석을 사용하는 리파지토리 설정 모두를 어떻게 선언 하시겠습니까?

주석은 하나의 속성 집합 (즉, 하나의 jpa : 저장소에만 해당)을 지원하는 것으로 보이며 여러 번 주석을 선언 할 수 없습니다.

해결법

  1. ==============================

    1.이 작업을 수행하는 데 도움이되는 '최소'다중 데이터 소스 프로젝트를 만들었습니다. Java 클래스 7 개와 다른 설정이 있으므로이 답변에 키 추출 만 게시 할 것입니다. GitHub에서 전체 프로젝트를 얻을 수 있습니다 : https://github.com/gratiartis/multids-demo

    이 작업을 수행하는 데 도움이되는 '최소'다중 데이터 소스 프로젝트를 만들었습니다. Java 클래스 7 개와 다른 설정이 있으므로이 답변에 키 추출 만 게시 할 것입니다. GitHub에서 전체 프로젝트를 얻을 수 있습니다 : https://github.com/gratiartis/multids-demo

    이 데모는 두 개의 JPA 엔티티를 설정합니다.

    @Entity public class Foo { /* Constructors, fields and accessors/mutators */ }
    @Entity public class Bar { /* Constructors, fields and accessors/mutators */ }
    

    이것들과 관련하여 우리는 두 개의 저장소를 생성 할 것입니다. Spring Data의 놀라운 점 덕분에 우리는 JpaRepository를 확장하는 인터페이스를 정의함으로써 완전히 완전한 기능을 갖춘 저장소를 얻을 수 있습니다.

    public interface FooRepository extends JpaRepository<Foo, Long> {}
    public interface BarRepository extends JpaRepository<Bar, Long> {}
    

    이제 우리는 이들 각각이 자체 데이터베이스에있는 테이블에 매핑되도록해야합니다.

    이를 위해 두 개의 별도 엔티티 관리자가 필요하며 각 엔티티 관리자마다 서로 다른 데이터 소스가 있습니다. 그러나 Spring Java config @Configuration 클래스에서는 @EnableJpaRepositories 주석 하나만 가질 수 있으며 각 주석은 하나의 EntityManagerFactory 만 참조 할 수 있습니다. 이를 위해 두 개의 별도 @Configuration 클래스 인 FooConfig와 BarConfig를 만듭니다.

    각 @Configuration 클래스는 내장 된 HSQL 데이터베이스를 기반으로 DataSource를 정의합니다.

    @Bean(name = "fooDataSource")
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setName("foodb").setType(EmbeddedDatabaseType.HSQL).build();
    }
    @Bean(name = "barDataSource")
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setName("bardb").setType(EmbeddedDatabaseType.HSQL).build();
    }
    
    @Bean(name = "barEntityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean lef = 
                new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource());
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("com.sctrcd.multidsdemo.domain.bar");
        lef.setPersistenceUnitName("barPersistenceUnit");
        lef.afterPropertiesSet();
        return lef.getObject();
    }
    @Bean(name = "fooEntityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean lef = 
                new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource());
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("com.sctrcd.multidsdemo.domain.foo");
        lef.setPersistenceUnitName("fooPersistenceUnit");
        lef.afterPropertiesSet();
        return lef.getObject();
    }
    

    각 구성은 위와 같이 자신의 dataSource () @Bean 메소드를 참조하는 EntityManagerFactory를 정의해야합니다. 또한 관리하는 @Entity bean에 대한 경로도 정의합니다. 다른 데이터 소스의 @Entity bean이 다른 패키지에 있는지 확인해야합니다.

    이 시점에서 각각의 설정이 핵심 영속 빈 (즉, entityManagerFactory)에 대한 기본 이름을 사용하면 Spring은 EntityManager 인터페이스와 함께 두 개의 Bean (동일한 이름을 가짐)이 있음을 알게됩니다. 그래서 하나가 선택 될 것입니다. 이로 인해 다음과 같은 오류가 발생합니다.

    Not an managed type: class com.sctrcd.multidsdemo.domain.bar.Bar
    

    이것은 데모 프로젝트의 한 지점에서 볼 수 있습니다 : https://github.com/gratiartis/multids-demo/tree/1-unnamed-entitymanager-beans

    이 예제에서 Spring은 "foodb"데이터베이스와 관련된 bean을 유선 화했으며 Bar는 해당 데이터베이스의 엔티티가 아니기 때문입니다. 불행히도 BarRepository는 Foo 엔티티 관리자와 연결되었습니다.

    우리는이 문제를 각 config 클래스에있는 모든 bean의 이름을 지정하여 해결합니다. 즉

    @Bean(name = "fooDataSource") public DataSource dataSource() { .. }
    @Bean(name = "fooEntityManager") public EntityManager entityManager() { .. }
    

    이 시점에서 프로젝트에서 테스트를 실행하려면 다음과 같은 경고가 표시 될 수 있습니다.

     No bean named 'entityManagerFactory' is defined.
    

    이것은 ... drumroll ... 우리는 기본 이름이 "entityManagerFactory"인 EntityManagerFactory가 없습니다. 하나는 "fooEntityManagerFactory"이고 다른 하나는 "barEntityManagerFactory"입니다. Spring은 기본 이름을 가진 무언가를 찾으므로, 상황을 다르게 연결하도록 지시해야합니다.

    그것이 밝혀 졌을 때, 이것은 매우 간단합니다. 각 @Configuration 클래스에 대해 @EnableJpaRepositories 주석에 올바른 참조를 넣기 만하면됩니다.

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "fooEntityManagerFactory", 
            transactionManagerRef = "fooTransactionManager",
            basePackages = {"com.sctrcd.multidsdemo.integration.repositories.foo"})
    public class FooConfig {
        // ...
    }
    
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "barEntityManagerFactory", 
            transactionManagerRef = "barTransactionManager",
            basePackages = { "com.sctrcd.multidsdemo.integration.repositories.bar" })
    public class BarConfig {
        // ...
    }
    

    보시다시피 각 @EnableJpaRepositories 주석은 특정 EntityManagerFactory 및 PlatformTransactionManager라는 이름을 정의합니다. 그들은 또한 어떤 저장소가 그 빈들과 연결되어야 하는지를 지정합니다. 이 예제에서는 저장소를 데이터베이스 별 패키지에 넣었습니다. 어노테이션에 includeFilters를 추가하여 각 저장소를 이름으로 정의 할 수도 있지만 데이터베이스별로 저장소를 분리하면 더 쉽게 읽을 수있게됩니다.

    이 시점에서 스프링 데이터 저장소를 사용하여 두 개의 개별 데이터베이스에서 엔티티를 관리하는 작업 응용 프로그램을 만들어야합니다. 위의 링크에서 프로젝트를 가져 와서이 문제를 확인하기 위해 테스트를 실행하십시오. 다행히도이 답변은 더 많은 사람들에게 유용합니다. 관리 할 수있는 코드를 가능한 한 깔끔하게 정리하는 데 상당한 시간을 할애했습니다. 답변이나 데모 프로젝트의 개선을위한 아이디어는 언제나 환영합니다.

  2. ==============================

    2.@Configuration 클래스 두 개 (@Configuration 당 하나의 @EnableJpaRepositories)에 넣으십시오.

    @Configuration 클래스 두 개 (@Configuration 당 하나의 @EnableJpaRepositories)에 넣으십시오.

  3. from https://stackoverflow.com/questions/15008809/multiple-jparepositories-in-xml-config-how-to-configure-with-enablejpareposit by cc-by-sa and MIT license