반응형

Programming/Spring 7

fetch join은 페이징 불가? (관계에 따른 진실과 Querydsl의 대응 전략)

이 글은 JPA N+1 문제 해결 전략에서 이어지는 글입니다.먼저 N+1 문제의 배경과 해결 방법을 알고 싶다면 이전 글을 참고해주세요! JPA를 쓰다 보면 fetch join은 성능 최적화의 필수 도구처럼 느껴지지만,페이징과 함께 쓰려 할 때는 자주 “불가능하다”는 이야기를 듣게 됩니다.이 글에서는 fetch join과 페이징이 충돌하는 근본적인 이유,그리고 Querydsl에서는 어떻게 다르게 동작하는지, 관계에 따라 어떤 문제가 발생할 수 있는지를 정리해보았습니다.1. fetch join이란?JPA의 fetch = FetchType.LAZY 설정은 연관 엔티티를 실제로 사용할 때 쿼리를 발생시킵니다.이를 해결하기 위한 대표적인 방법이 JPQL의 JOIN FETCH입니다.@Query("SELECT m ..

Programming/Spring 2025.07.15

JPA N+1 문제 정복하기: fetch join부터 batch size까지 실전 해결 전략

JPA를 쓰다 보면 한 번쯤 겪게 되는 대표적인 성능 이슈, 바로 N+1 문제입니다.이 글에서는 N+1 문제가 어떻게 발생하는지, 그리고 실제로 어떻게 해결할 수 있는지 정리해보았습니다.1. N+1 문제란?JPA에서는 연관 관계가 기본적으로 LAZY 로딩입니다.@ManyToOne(fetch = FetchType.LAZY)private Team team;이 설정으로 인해, 연관된 엔티티는 실제로 접근하는 시점에 쿼리가 발생합니다.예시:List members = memberRepository.findAll();for (Member m : members) { System.out.println(m.getTeam().getName()); // N개의 쿼리 발생!}Member 전체를 가져오는 쿼리 1번각 Me..

Programming/Spring 2025.07.15

Spring DI란? 주입 방식의 종류와 기본 개념

Spring에서 가장 중요한 개념 중 하나인 DI(Dependency Injection, 의존성 주입)은 객체 간의 의존 관계를 외부에서 주입해주는 방식입니다. 이 글에서는 DI가 무엇인지, 그리고 어떤 방식으로 의존성을 주입할 수 있는지 정리해보겠습니다.✅ 의존성 주입(DI)이란?객체 간의 협업이 필요할 때, 직접 객체를 생성하지 않고 외부에서 주입받는 방식입니다.Spring에서는 DI를 통해 객체 간 결합도를 낮추고, 테스트 및 유지보수를 용이하게 만듭니다.예: UserService가 UserRepository를 필요로 할 때 직접 생성하지 않고 외부에서 주입받음💡 DI 방식의 종류Spring에서는 의존성 주입을 다음과 같은 방식으로 지원합니다:1. 필드 주입 (Field Injection)@Com..

Programming/Spring 2025.07.14

[Part 2] JPA 실전 설계 전략: DTO, Entity, VO, Projection 구분법

Spring 프로젝트를 설계할 때, 패키지 구조만큼 중요한 것이 바로 모델 설계의 분리 원칙입니다.특히 JPA를 사용할 때는 다음과 같은 고민이 자주 발생하죠:Entity를 바로 응답에 써도 될까?DTO는 어디까지 분리할까?값 객체(VO)는 어떤 걸로 만들면 좋을까?Projection은 언제 쓰는 게 좋을까?이번 글에서는 실무 관점에서 DTO, VO, Projection을 어떻게 구분하고 활용할지를 정리했습니다.🔄 DTO와 Entity는 왜 분리할까?항목DTOEntity역할요청/응답 데이터 전달DB 매핑 + 비즈니스 로직위치Controller ↔ Client도메인 내부, Repository ↔ DB특징직렬화/역직렬화 최적화영속성 관리 대상, 로직 포함 가능예시UserResponseDTO, OrderRe..

Programming/Spring 2025.07.14

[Part 1] Spring 패키지 구조 설계 전략: MVC vs 도메인 중심

Spring 프로젝트를 시작할 때 가장 먼저 마주하는 선택지 중 하나가 “패키지 구조를 어떻게 나눌 것인가?”입니다.많은 분들이 controller, service, repository처럼 계층 중심 구조(MVC 기반)로 시작하지만,실무에서는 도메인 중심 구조로 점차 옮겨가는 추세입니다.이번 글에서는 두 구조의 차이점, 장단점, 선택 기준을 구체적인 예시와 함께 정리해보았습니다.📌 구조 비교: MVC vs 도메인 중심항목MVC 패턴 기반 구조도메인 중심 구조기준역할 계층별(controller, service, repository)도메인 기능별(user, product, order)장점역할 분리가 명확익숙한 구조응집도 높음모듈화 용이협업에 유리단점같은 도메인의 코드가 분산됨초보자에게 익숙하지 않을 수 있..

Programming/Spring 2025.07.14

Spring 트랜잭션에서 `@Transactional`이 무시되는 이유와 주의할 점

Spring에서는 @Transactional을 이용해 트랜잭션을 손쉽게 적용할 수 있지만, 프록시 기반이라는 특성 때문에 내부 메소드 호출 시 트랜잭션이 적용되지 않는 문제(self-invocation) 가 발생할 수 있습니다.이 글에서는 다음 세 가지 핵심 내용을 다룹니다:@Transactional은 프록시 객체를 통해 트랜잭션을 제어자기 호출(self-invocation) 은 프록시를 우회하므로 트랜잭션이 무시됨트랜잭션이 적용되지 않으면 어떤 일이 발생하는지1. @Transactional은 프록시를 통해 트랜잭션을 제어Spring은 @Transactional을 감지해 실제 객체가 아닌 프록시 객체를 생성합니다. 이 프록시가 트랜잭션을 시작하고, 메소드 실행 후 커밋 또는 롤백합니다.@Servicepu..

Programming/Spring 2025.07.14

[Spring Boot] JPA vs Querydsl - 동적 쿼리 필터링 어떻게 다를까?

Spring Boot에서 JPA를 쓰다 보면 동적 조건이 있는 검색 API를 구현할 일이 많습니다. 이때 JPA만으로 구현했을 때와 Querydsl을 함께 사용했을 때의 차이를 실제 코드로 비교해보며, 실무에서 왜 Querydsl을 많이 쓰는지 살펴보겠습니다.💡 시나리오: 조건부 사용자 검색아래 조건들을 입력받아 사용자(User)를 검색하는 API를 만든다고 가정합니다.이름(name)은 포함 검색 (LIKE)나이(age)는 이상 조건 (greater than or equal)가입일(createdAt)은 이후 날짜부터 검색 (after)세 조건은 모두 선택적으로 들어올 수 있습니다.🔸 JPA만 사용할 때 (Criteria API 사용)public List searchUsers(String name, I..

Programming/Spring 2025.07.14
반응형