복붙노트

[SPRING] Spring 데이터 + 다중 데이터 소스가 있지만 하나의 리포지토리 세트 만있는 JPA

SPRING

Spring 데이터 + 다중 데이터 소스가 있지만 하나의 리포지토리 세트 만있는 JPA

나는 오늘이 무리를 연구 해왔고, 내가하고 싶은 일이 가능하지 않을 수도 있다고 생각하기 시작했다. 그래서 도움을 청할 수있는 Stackoverflow를 너에게 돌리고있다.

Spring 데이터 3.1.2 + JPA를 내 영속성 계층 (여기에 설명 된대로)과 함께 Java로 RESTful 서비스 플랫폼을 구축하고 있습니다. 내 데이터 모델 객체는 모두 Spring JpaRepository 인터페이스를 확장하는 인터페이스로 구현됩니다. 이 예제에서 볼 수 있듯이 모든 데이터가 하나의 데이터 소스로 잘 정리되어 있습니다. (표시된 데이터 소스는 Derby이지만, 이는 개발 용도로만 사용됩니다. 프로덕션에서는 Oracle을 사용합니다).

<jpa:repositories base-package="com.my.cool.package.repository"/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
  </property>
  <property name="packagesToScan" value="com.my.cool.package" />
  <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>

<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
  <property name="url" value="jdbc:derby:derbyDB" />
  <property name="username" value="dev" />
  <property name="password" value="notARealPassword" />
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
  <property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
</bean>

문제는이 응용 프로그램이 여러 (Oracle) 데이터베이스에 연결해야한다는 것입니다. 들어오는 각 요청에 포함 된 자격 증명에는 해당 요청을 수행하기 위해 이동할 데이터베이스를 응용 프로그램에 알리는 필드가 있습니다. 각 데이터베이스의 스키마는 동일하므로 각 데이터베이스에 별도의 저장소 인터페이스가 필요하지 않습니다.

상당한 양의 인터넷 검색 결과가 이것이 일반적인 시나리오임을 분명히합니다. 위트하려면 :

그리고 (실제로?) Spring 개발자가 실제로 블로그 주제와 관련이없는 블로그 게시물이 있습니다.하지만 누군가가 주석에이를 표시하고 저자가 몇 가지 정보로 응답합니다.

http://blog.springsource.org/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/#comment-198835

이 문제를 해결하는 방법은 여러 개의 EntityManagerFactories를 정의하고 각각을 적절한 저장소에 연결하는 것입니다.

<jpa:repositories base-package="com.my.cool.package.repository1" entity-manager-factory-ref="firstEntityManagerFactory" />
<jpa:repositories base-package="com.my.cool.package.repository2" entity-manager-factory-ref="secondEntityManagerFactory" />

그러나 필자가 언급했듯이 모든 데이터 소스에서 저장소를 다시 사용하기를 원하기 때문에이 방법은 효과가없는 것처럼 보입니다.

요청에서 관련 정보를 취하는 로직을 내 코드에 사용하는 방법이 없다는 것을 알고 있으며이를 사용하여 사용할 데이터 소스 (또는 EntityManagerFactory)를 결정합니다. 내가 고민하는 부분은 해당 데이터 소스 / EntityManagerFactory에 대한 핸들을 가져와 내 리포지토리 개체에 "주입"하는 것입니다. 어떤 아이디어?

해결법

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

    1.멀티 테넌트 (multi-tenant) 방식 (실제로 데이터 소스에 요청을 할당하고 전체 요청에 대해이를 고수하는 방식)에서 다른 데이터 소스를 실제로 사용하는 경우에는 AbstractRoutingDataSource를 살펴 봐야합니다. 그것은 본질적으로 DataSource Map을 유지하는 방법과 콜백 메소드가 결국 사용할 DataSource를 조회하는 데 사용되는 키를 반환하는 방법을 제공합니다. 이 메소드의 구현은 보통 스레드 바운드 키를 찾아 반환합니다 (또는 데이터 소스 맵 키에 차례로 매핑). 먼저 웹 구성 요소가 해당 키를 스레드의 첫 번째 위치에 바인딩하는지 확인해야합니다.

    멀티 테넌트 (multi-tenant) 방식 (실제로 데이터 소스에 요청을 할당하고 전체 요청에 대해이를 고수하는 방식)에서 다른 데이터 소스를 실제로 사용하는 경우에는 AbstractRoutingDataSource를 살펴 봐야합니다. 그것은 본질적으로 DataSource Map을 유지하는 방법과 콜백 메소드가 결국 사용할 DataSource를 조회하는 데 사용되는 키를 반환하는 방법을 제공합니다. 이 메소드의 구현은 보통 스레드 바운드 키를 찾아 반환합니다 (또는 데이터 소스 맵 키에 차례로 매핑). 먼저 웹 구성 요소가 해당 키를 스레드의 첫 번째 위치에 바인딩하는지 확인해야합니다.

    그렇게 설정했다면 Spring 설정은 AbstractRoutingDataSource의 하위 클래스를위한 빈을 설정하고 DataSources의 맵을 파이프로 파이프한다. 스프링 데이터 JPA 설정은 기본 방식으로 유지됩니다. EntityManagerFactoryBean은 AbstractRoutingDataSource를 참조하며 단일 요소 만 있습니다.

  2. from https://stackoverflow.com/questions/12612288/spring-data-jpa-with-multiple-datasources-but-only-one-set-of-repositories by cc-by-sa and MIT license