JPA를 사용하다보면, extends JPARepository
를 통해 쉽게 하나의 CRUD 레포지토리 개발이 가능해 매우 편리하다는 것을 깨닫게 된다.
하지만, 안정성적인 측면에서 생각해보았을 때, 이것은 그렇게 좋은 것이 아니라는 생각이 든다.
기본적으로 모든 기능을 제공하기 때문에 save, delete, count 등 기본적으로 제공하는 모든 메서드에 접근할 수 있게 되고,
코딩은 혼자만 하는 것이 아니기 때문에 모두가 함께 사용하는 레포지토리에서, 누가 어떻게 쓸 지는 알 수 없는 것이다.
이로 인해, JPARepository에 대해 기능을 제한하여, 안정성을 보장할 수 있는데, 이에 대해 학습하여 작성하고자 한다.
@RepositoryDefinition
애너테이션을 통해 BeanDefinition 에 직접 접근하여, 프로그래밍으로 주입받을 구현체 메소드를 직접 지정해우저 요청이 가능하다.
@RepositoryDefinition(domainClass = Thread.class, idClass = Long.class)
public interface ThreadRepository {
Thread save(Thread thread);
List<Thread> findAll();
}
다음과 같이 사용되는데, domainClass, idClass를 명시해주어 어떤 객체에 대한 레포지토리인지 명시해준다.
이 경우, 메서드에 해당하는 기능을 스프링 데이터 JPA
에서 기본적으로 구현해주는 부분을 제공해주어 이를 통해 기능구현이 되며, 동시에 기능을 제한시킬 수 있게된다.
@NoRepositoryBean
public interface MyRepository<T, ID extends Serializable> extends Repository<T, ID> {
<E extends T> E save(E entity);
List<T> findAll();
}
public interface ThreadRepository extends MyRepository<Thread, Long> {
}
다음과 같이 @NoRepositoryBean
애너테이션을 통해, 직접적으로 사용되지 않는 레포지토리 빈 임을 명시해주고,
사용하고싶은 기능들을 명시해준다. 해당 기능은 공통적으로 사용할 수 있게 되며,
특정 레포지토리 입장에서는, 해당 Repository 인터페이스를 상속받아 기능을 제한하는 방식으로 사용된다.
아무 생각없이 extends JPARepository
를 하며 편하게 사용해왔었는데,
항상 조금만 더 생각하면 알 수 있는 부분들을 놓쳤던 것 같다.
나 혼자 코딩을 하지 않는다는 점과, 나도 나를 믿으면 안된다는 것 같은 것이다.
안정성은 나의 머리로 보장하는 것이 아니라, 코드로 보장하는 것이다.
프로그래머니까 코드를 믿고, 이를 구현할 줄 알아야 하는 것 같다.
안정성 있는 코드를 작성하자!
믿을 건 코드밖에 없다.