전체 글

yeongkeeDev

    다이내믹 프록시를 활용한 JPA QueryCounter 구현기

    들어가며 JPA와 같은 ORM을 사용할 때, 지연 로딩과 같은 기능을 무분별하게 이용하다보면 원래 의도했던 개수보다 더 많은 쿼리가 발생하기도 한다. ORM에서 흔히 발생하는 N + 1 문제도 개발자의 의도와 다르게 N번의 쿼리가 더 발생하게 된다. 이렇듯 ORM을 사용하다보면 예상하지 못한 개수의 쿼리가 발생하기도 하는데, 이를 한눈에 파악하기는 쉽지 않다. 물론 JPA의 show-sql 기능을 사용하면 로그에 쿼리가 출력되기는 하지만, 좀 더 쉽게 알아볼 수 있는 방법이 필요하다는 생각이 들었고, 이를 위해 다이내믹 프록시를 활용하여 JPA QueryCounter를 구현해보기로 하였다. 여기서는 Spring Data JPA를 기반으로 설명한다는 점을 알고가도록 하자. 기본 원리 JPA QueryCou..

    다이내믹 프록시를 이용한 부가 기능 분리

    부가 기능 분리 부가 기능(Ex. 트랜잭션)은 비즈니스 로직과 성격이 다르기 때문에 분리해줄 필요가 있다. 이러한 분리는 프록시를 사용하여 진행할 수 있는데, 일반적인 프록시를 사용하게 되면 몇 가지 문제점과 마주하게 된다. 어떠한 문제점이 있는지 알아보고, 이를 다이내믹 프록시로 개선시켜보도록 하자. 프록시 적용해보기 먼저 다음은 프록시를 적용하여 부가 기능과 핵심 기능을 분리한 예제이다. public interface UserService { void add(User user); void upgradeLevels(); } public class UserServiceTx implements UserService { private UserService userService; private Platform..

    의존관계 주입(DI)과 객체 지향 설계

    의존관계 주입(Dependency Injection)이란 의존관계 주입(DI)이란 구체적인 의존 오브젝트와 그것을 사용할 주체 오브젝트를 런타임 시에 연결해주는 작업을 말한다. 조금 더 구체적으로는 다음과 같은 세 가지 조건을 충족하는 작업을 말한다. 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스에만 의존하고 있어야 한다. 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제 3의 존재가 결정한다. 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 주입해줌으로써 만들어진다. 이러한 의존관계 주입은 유연성, 재사용성, 테스트 용이성 등 여러 가지 장점을 가져다주는데, 여기서는 객체 지향 설계 원칙인 단일 책임 원칙(SRP)과 개방-폐쇠 원칙(OCP)을 지킬..

    JPA 데이터 뻥튀기 문제 알아보기

    들어가며 프로젝트를 진행하던 도중 의도와는 다른 개수의 엔티티가 조회되는 흔히 "데이터 뻥튀기"라고 불리는 문제가 발생하였다. 해당 문제가 무엇이고, 왜 발생하는지, 그리고 어떻게 해결할 수 있는지에 대해 알아보도록 하자. 일단 문제가 발생한 엔티티 간의 연관관계를 간단히 나타내보면 다음과 같다. 모든 연관관계가 1 : N 이라는 것을 알 수 있다. 여기서 하나의 Task가 여러 개의 Comment를 가질 수 있다는 점을 주목하고 넘어가도록 하자. 그러면 이제 문제의 상황을 만들어보도록 하겠다. 엔티티 구현 먼저 데이터 뻥튀기 문제에서 사용할 엔티티는 다음과 같다. // User.java @Getter @NoArgsConstructor @Entity public class User { @Id @Gener..