반응형

lazyloading 7

[Spring JPA 공식 문서 기반] 17. Batch Size와 Hibernate 최적화 전략

16편에서는 Fetch Join이“N+1 문제를 해결하는 만능 도구가 아니라, 조회 범위를 명시하는 선언”이라는 점과, 그 구조적 한계를 살펴봤습니다.그래서 다음 질문이 자연스럽게 등장합니다.Fetch Join이 안 되는 상황에서는 N+1을 어떻게 완화해야 할까?이때 가장 자주 등장하는 해답이 바로Batch Size입니다.1. Batch Size는 왜 등장했을까Batch Size는 N+1 문제를“없애는” 기능이 아니라 “완화하는” 전략입니다.특히 다음 조건에서 필요해졌습니다.연관관계가 LAZY로 설정되어 있고Fetch Join을 쓰기 어렵거나페이징이 필요한 조회즉,Fetch Join의 한계를 메우기 위한 현실적인 대안으로 등장했습니다.2. Batch Size의 기본 아이디어Batch Size의 아이디어는..

[Spring JPA 공식 문서 기반] 16. Fetch Join의 한계는 어디까지일까

15편에서는 N+1 문제가Lazy Loading의 문제가 아니라, 조회 시점과 탐색 시점이 분리된 구조의 결과라는 점을 살펴봤습니다.그래서 자연스럽게 등장하는 해결책이Fetch Join입니다.이번 글에서는 Fetch Join이어디까지는 훌륭한 해결책이고어디서부터는 구조적 한계가 되는지를 Spring JPA 공식 문서 관점에서 정리해보겠습니다.1. Fetch Join은 무엇을 해결해 주는가Fetch Join은 JPQL 단계에서 연관 엔티티를“같은 쿼리로 함께 로딩하라”고 명시적으로 선언하는 방법입니다.select o from Order ojoin fetch o.member이 한 줄로:N+1 문제 제거Lazy 로딩 제어조회 쿼리 수 감소라는 명확한 이점을 얻을 수 있습니다.그래서 Fetch Join은N+1 ..

[Spring JPA 공식 문서 기반] 15. N+1 문제는 왜 구조적으로 발생할까

14편에서는 Lazy Loading이“항상 터지는 기능처럼 보이는 이유”가 실제로는 트랜잭션과 엔티티 상태를 잘못 다룬 결과라는 점을 살펴봤습니다.이번 글에서는 Lazy Loading과 항상 함께 언급되는,N+1 문제가왜 실수로 생기는 버그가 아니라 구조적으로 발생할 수밖에 없는 문제인지를 Spring JPA 공식 문서 관점에서 정리해보겠습니다.1. N+1 문제를 단순한 “실수”로 보면 안 되는 이유N+1 문제는 보통 이렇게 설명됩니다.“쿼리를 잘못 써서 SELECT가 N번 더 나간다”이 설명은절반만 맞습니다.왜냐하면 N+1 문제는JPA의 동작 방식과객체 그래프 탐색 모델이결합되면서의도하지 않아도 자연스럽게 발생하기 때문입니다.2. N+1의 기본 구조다음과 같은 상황을 생각해봅시다.List orders ..

[Spring JPA 공식 문서 기반] 14. Lazy Loading은 왜 항상 터질까

13편에서는 즉시 로딩(EAGER)이“항상 함께 로딩한다”는 전제 때문에 실무에서 구조적인 문제를 만들 수밖에 없다는 점을 살펴봤습니다.그 다음으로 자연스럽게 나오는 말이 있습니다.“그럼 Lazy는 안전한가요?”하지만 실무에서는 오히려“Lazy는 항상 터진다”는 인식이 더 강합니다.이번 글에서는 이 인식이 왜 생겼는지, 그리고 그 오해의 정체가 무엇인지 공식 문서 관점에서 정리해보겠습니다.1. Lazy Loading은 원래 문제가 아니다먼저 분명히 해야 할 사실이 있습니다.Lazy Loading 자체는 문제 있는 기능이 아니다오히려 JPA 공식 문서 기준으로 보면, Lazy Loading은연관관계를 필요할 때만 로딩하고불필요한 JOIN을 피하며조회 성능을 제어하기 위한 기본 전략입니다.즉,Lazy는 “위..

[Spring JPA 공식 문서 기반] 11. OSIV는 왜 기본값이었고, 왜 문제였을까

10편에서는 읽기 전용 트랜잭션이“쓰기 방지 옵션”이 아니라 “조회용 Persistence Context를 올바르게 유지하기 위한 선언”이라는 점을 살펴봤습니다.이번 글에서는 그 흐름의 마지막 퍼즐 조각,OSIV(Open Session In View)가왜 기본값이었고, 왜 문제가 되었는지를 공식 문서 관점에서 정리해보겠습니다.1. OSIV는 어떤 문제를 해결하려고 등장했을까OSIV가 등장한 배경은 아주 현실적인 문제였습니다.“컨트롤러나 뷰에서 Lazy Loading이 자꾸 터진다”당시의 전형적인 구조는 이랬습니다.Service 계층에서 트랜잭션 종료Controller / View에서 엔티티 접근LazyInitializationException 발생OSIV는 이 문제를 아주 단순한 방식으로 해결합니다.“요..

[Spring JPA 공식 문서 기반] 10. 읽기 전용 트랜잭션의 진짜 의미

9편에서는 트랜잭션이 없을 때 JPA의 핵심 기능이“왜 반쪽짜리로 무너지는지”를 Persistence Context와 엔티티 상태 흐름을 통해 정리했습니다.이번 글에서는 그 다음으로 자연스럽게 따라오는 질문,“그렇다면 읽기만 하는 경우에도 왜 트랜잭션을 써야 할까?”에 답해보겠습니다.1. 읽기 전용 트랜잭션은 왜 오해를 부를까@Transactional(readOnly = true)를 보면 많은 개발자가 이렇게 이해합니다.“이 메서드는 DB에 쓰기가 안 나간다”하지만 이 이해는정확하지 않습니다.읽기 전용 트랜잭션은쓰기 자체를 금지하는 기능 ❌JPA의 동작 방식을 힌트로 알려주는 설정 ⭕입니다.2. 읽기 전용 트랜잭션의 진짜 목적Spring JPA 공식 문서 기준으로, 읽기 전용 트랜잭션의 목적은 다음 두 ..

[Spring JPA 공식 문서 기반] 9. 트랜잭션이 없으면 JPA는 왜 반쪽짜리일까

8편에서는 EntityManager가 왜 Thread-safe 하지 않은지, 그리고 그 이유가“EntityManager는 트랜잭션에 바인딩된 상태 관리자”라는 점에 있음을 정리했습니다.이번 글에서는 이 논의를 한 단계 더 밀어보겠습니다.트랜잭션이 없으면 JPA는 실제로 어떻게 동작할까?결론부터 말하면,트랜잭션이 없는 JPA는 핵심 기능의 절반이 동작하지 않습니다.그래서 우리는“JPA는 트랜잭션 기반 기술”이라고 말합니다.1. 가장 흔한 착각부터 짚자다음과 같은 코드를 보면 많은 개발자가 이렇게 기대합니다.public void updateMember() { Member m = em.find(Member.class, 1L); m.setName("newName");}겉보기에는:엔티티를 조회했고상태를..

반응형