FetchType과 N+1 문제
1. 즉시 로딩(EAGER)과 지연 로딩(LAZY) 📌 FetchType 기본값 정리 JPA 연관관계 어노테이션의 기본 FetchType은 다음과 같다. 어노테이션 기본 FetchType @ManyToOne EAGER @OneToOne EAGER @OneToMany LAZY @ManyToMany LAZY @ManyToOne과 @OneToOne의 기본값...
1. 즉시 로딩(EAGER)과 지연 로딩(LAZY) 📌 FetchType 기본값 정리 JPA 연관관계 어노테이션의 기본 FetchType은 다음과 같다. 어노테이션 기본 FetchType @ManyToOne EAGER @OneToOne EAGER @OneToMany LAZY @ManyToMany LAZY @ManyToOne과 @OneToOne의 기본값...
1. 프로젝트 생성 📌 Spring Initializr 설정 (3.x) start.spring.io에서 프로젝트를 생성할 때 선택해야 할 항목은 다음과 같다. 항목 선택값 이유 Project Gradle - Kotlin Kotlin DSL 기준으로 진행. Groovy보다 타입 안전하고 IDE 자동완성이 좋음 Language Java Spring B...
1. JDBC의 한계 📌 JDBC란 JDBC(Java Database Connectivity)는 자바 표준 API로, 자바 애플리케이션이 관계형 데이터베이스에 접근할 수 있게 해주는 인터페이스 명세다. java.sql 패키지 하위에 정의된 Connection, PreparedStatement, ResultSet 등이 모두 JDBC 스펙에 해당한다. 실...
1. JPQL 기초 📌 SQL vs JPQL JPQL(Jakarta Persistence Query Language)은 테이블과 컬럼이 아닌 엔티티와 필드를 기준으로 작성하는 객체 지향 쿼리 언어다. 1 2 3 4 -- SQL — 테이블명, 컬럼명 기준 SELECT m.member_id, m.member_name, m.age FROM member m ...
1. 영속성 컨텍스트란 JPA를 처음 접하면 “왜 DB에 바로 저장하지 않고 영속성 컨텍스트라는 중간 단계가 있는 걸까?”라는 의문이 생긴다. 예를 들어 한 HTTP 요청 안에서 아래와 같은 일이 벌어진다고 생각해보자. 1 2 3 4 Member member = findById(1L); // SELECT → DB 왕복 1번 member.setName(...
1. 실습 도메인 소개 이론으로 배운 영속성 컨텍스트 개념을 실제 코드로 확인하는 실습이다. 도메인은 도서 대출 시스템으로, Book 엔티티 하나로 생명주기 · 1차 캐시 · 쓰기 지연 · 더티 체킹 전체를 단계별로 체험한다. 1 2 3 4 5 6 Step 1. Book 엔티티 작성 ← @Entity, @Column, @Enumerated 적용 Ste...
1. Criteria API란 Criteria API는 자바 코드로 타입 안전하게 동적 쿼리를 작성하는 JPA 표준 API다. JPQL이 문자열 기반이라 오타나 필드명 변경 시 런타임에야 오류를 발견하는 반면, Criteria API는 컴파일 타임에 타입 오류를 잡을 수 있다. 1 2 3 4 5 // JPQL — 문자열 기반. 오타가 있어도 컴파일 타...
1. @Entity @Entity는 해당 클래스가 JPA가 관리하는 엔티티임을 선언하는 어노테이션이다. 이 어노테이션이 붙어야만 JPA가 이 클래스를 인식하고 DB 테이블과 매핑한다. 📌 반드시 지켜야 할 제약 기본 생성자가 필수다. JPA는 DB에서 조회한 결과를 엔티티 객체로 변환할 때 내부적으로 리플렉션(Reflection)을 사용한다. 이 과정...
1. 실습 구조 기존 Member와 Book에 LoanRecord(대출 기록)를 추가해서 연관관계 매핑 전체를 단계별로 실습한다. 1 2 3 4 5 6 7 8 9 10 Step 1. Book에 @OneToMany 양방향 추가 Step 2. Member에 @OneToMany + cascade + orphanRemoval 추가 Step 3. LoanRec...
1. QueryDSL 설정 📌 의존성 및 Q클래스 생성 설정 (Spring Boot 3.x / Gradle Kotlin DSL) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // build.gradle.kts plugins { kotlin("...
1. 연관관계 매핑이 필요한 이유 연관관계 매핑을 이해하려면 항상 세 가지 개념을 함께 생각해야 한다. 방향: 단방향(한쪽만 참조), 양방향(서로 참조) 다중성: @OneToOne / @OneToMany / @ManyToOne / @ManyToMany 연관관계 주인: 양방향일 때 FK를 실제로 관리하는 쪽 2. @ManyToOne — 다대일 단방향 가...
1. 벌크 연산과 읽기 전용 트랜잭션 📌 @Modifying 벌크 UPDATE/DELETE 벌크 연산은 영속성 컨텍스트를 거치지 않고 DB에 직접 실행된다. 이 때문에 실행 전후로 영속성 컨텍스트 상태와 DB 상태가 불일치하는 문제가 생길 수 있다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // ...
1. Repository 계층 구조 📌 인터페이스 상속 다이어그램 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 «interface» Repository<T, ID> │ 마커 인터페이스 — 메서드 없음. Spring이 스캔 대상을 식별하는 용도 │ «interface» CrudRepository<T, ...
1. QueryDSL과 커스텀 Repository 1 2 3 4 5 6 7 8 9 JpaRepository만으로는 뭐가 부족한가? ↓ 커스텀 Repository 패턴이란 무엇인가? ↓ 동적 쿼리를 직접 짜면 왜 힘든가? ↓ QueryDSL이 그 문제를 어떻게 해결하는가? ↓ 커스텀 Repository + QueryDSL = 완성된 전체 그림 2. Jp...
1. 동시성 제어 — 낙관적·비관적 잠금 📌 낙관적 잠금 (Optimistic Lock) — @Version 낙관적 잠금은 “대부분의 트랜잭션에서 충돌이 없을 것”이라고 낙관적으로 가정하고, 실제 충돌이 발생한 시점에 예외를 던지는 방식이다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Entity publi...