본문 바로가기

Spring/JPA

Spring JPA - 다양한 스프링 데이터 모듈과 함께 리포지토리 사용하기

 

 

다양한 스프링 데이터 모듈과 함께 리포지토리 사용하기

정의된 모든 리포지토리 인터페이스가 Spring Data 모듈에 바인딩됨

고유한 Spring Data 모듈을 사용하면 작업이 간단해짐

때때로 2개 이상 Spring 모듈을 사용하게 됨

리포지토리 지속성 기술을 구별해서 정의해야함

여러 리포지토리를 감지하면 Spring Data는 엄격한 저장소 구성 모드가 됨: 저장소 또는 도메인 클래스에 대한 세부 정보를 사용하여 리포지토리 정의에 대한 Spring Data 모듈 바인딩을 결정함

 

1. 모듈별로 특정한 리포지토리를 확장하여(상속받아)정의하면 특정 모듈은 유효함 -> 모듈별로 다른 리포지토리 사용가능

2. 도메인 클래스에 모듈별로 특정한 어노테이션을 달면 그 특정 모듈은 유효함 -> 써드파티 어노테이션(JPA의 @Entity) 또는 Spring 자체 어노테이션(Data MongoDB와 Elasticsearch @Document)를 제공

 

// 1. 특정한 인터페이스 모듈을 사용한 리포지토리 정의
// MyRepository와 UserRepository는 JpaRepository를 확장하여(상속 받아) Spring Data JPA 모듈에 대해 유효한 후보자
interface MyRepository extends JpaRepository<User, Long> { }

@NoRepositoryBean
interface MyBaseRepository<T, ID> extends JpaRepository<T, ID> { … }

interface UserRepository extends MyBaseRepository<User, Long> { … }


// 2. 일반 인터페이스를 사용한 리포지토리 정의
// AmbiguousRepository와 AmbigousUserRepository는 각각 Repository, CrudRepository를 확장(상속)
// 유일한 Spring Data 모듈을 사용할 때는 괞찮지만,
// 다양한 Spring Data 모듈을 사용하면 그 리포지토리는 바인딩되야하는 특정한 Spring Data를 구별할 수 없음
interface AmbiguousRepository extends Repository<User, Long> { … }

@NoRepositoryBean
interface MyBaseRepository<T, ID> extends CrudRepository<T, ID> { … }

interface AmbiguousUserRepository extends MyBaseRepository<User, Long> { … }


// 3. 어노테이션이 있는 도메인 클래스를 사용한 리포지토리 정의
// PersonRepository를 참조하는 Person은 JPA 어노테이션 @Entity가 달려있으므로 이 리포지토리는 명확하게 Spring Data JPA에 속함
// UserRepository를 참조하는 User는 MongoDB의 어노테이션 @Document가 달려있으므로 이 리포지토리는 Spring Data MongoDB에 속함 
interface PersonRepository extends Repository<Person, Long> { … }

@Entity
class Person { … }

interface UserRepository extends Repository<User, Long> { … }

@Document
class User { … }


// 🚫 4. 혼합 어노테이션이 있는 도메인 클래스를 사용한 리포지토리 정의
// JPA와 Spring Data MongoDB 어노테이션을 모두 사용하는 도메인 클래스
// Spring Data는 2개의 리포지토리를 구분할 수 없으므로 정의되지 않은 동작 발생
interface JpaPersonRepository extends Repository<Person, Long> { … }

interface MongoDBPersonRepository extends Repository<Person, Long> { … }

@Entity
@Document
class Person { … }

 

Configuration 클래스의 기본 패키지(basePackages)의 범위를 지정하는 어노테이션 사용하여 리포지토리를 구별

@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
class Configuration { … }