spring JPA를 사용하다 보면, 다음과 같이 JpaRepository를 상속한 Interface를 만들게 됩니다.
interface MyBaseRepository<T, ID> extends JpaRepository<T, ID> { … }
이러한 JpaRepository 상속 방식의 장점은 바로 메서드 쿼리 방식으로,
Entity 필드를 findBy{Field_1}And{Field_2} 와 같이 작성하면 WHERE field_1 = {Field_1} AND {Field_2} 같은 방식으로 쿼리 조건을 만들어준다는 장점이 있습니다.
해당 방식의 주의할 점은, 메서드 쿼리가 만들어지기 위해서는 Entity의 필드를 참조하기 때문에, 반드시 Entity의 필드명 혹은 쿼리 관련 키워드가 와야 한다는 점입니다.
문제는 해당 JpaRepository 외에 다음과 같이 다른 커스텀 Repository를 사용할 때, findAll~ 또는 FindBy 방식의 메서드 네이밍을 사용하는 경우, JpaRepository를 상속한 Repository가 Bean으로 등록되는 순간에 커스텀 Repository 메서드에서 필드를 찾지 못 하는 에러가 발생하게 됩니다.
@Table("my_entity")
@Entity
class MyEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
@Column(name = "name")
var name: String
)
interface MyEntityRepository: JpaRepository<MyEntity, Long>, CustomMyEntityRepository {
findByName(name: String): Optional<MyEntity> // 메서드 네이밍
}
interface CustomMyEntityRepository {
findByFoo(bar: String): MyEntity // Foo라는 필드가 없기 때문에 오류 발생
}
@NoRepositoryBean
해결 방법은 JPA 메서드 쿼리 방식을 따르지 않는 메서드 네이밍을 짓는 방법이 있지만, 이번에 소개할 내용은 Spring Data에서 제공하는 @NoRepositoryBean 이라는 어노테이션입니다.
해당 어노테이션은, JpaRepository를 사용하는 동시에 다른 커스텀 Repository를 사용할 때 해당 Inerface에 어노테이션을 다음과 같이 붙여주게 되면, 해당 Inferface는 JPA Repository Bean이 등록될 때 무시하게 되어, 이전과 같은 오류가 발생하지 않습니다.
@NoRepositoryBean
interface CustomMyEntityRepository {
findByFoo(bar: String): MyEntity // 쿼리 메서드 네이밍 방식이지만, Repository 등록 시에 제외 됨
}
참고
Defining Repository Interfaces :: Spring Data JPA
To define a repository interface, you first need to define a domain class-specific repository interface. The interface must extend Repository and be typed to the domain class and an ID type. If you want to expose CRUD methods for that domain type, you may
docs.spring.io
'Spring Framework > Data' 카테고리의 다른 글
[SpringBoot] JPA QueryDSL 의존성 querydsl-apt는 왜 필요할까? (0) | 2025.03.21 |
---|---|
[SpringBoot] Spring Transaction에 대하여 (0) | 2025.01.06 |
JPA @DataJpaTest - 환경구성 (0) | 2023.12.12 |
JPA findAll()은 어떻게 쿼리 결과를 객체로 파싱할까? (feat. 메서드 호출 과정) (0) | 2023.11.17 |
Hibernate 6.2 업데이트 시, Kotlin @OneToMany 제네릭 타입 이슈 (0) | 2023.10.24 |