기본 콘텐츠로 건너뛰기

라벨이 Hibernate인 게시물 표시

JPA 기본 키 생성 전략: IDENTITY, SEQUENCE, TABLE, AUTO를 언제 선택할까

JPA 기본 키 생성 전략: IDENTITY, SEQUENCE, TABLE, AUTO를 언제 선택할까 빠른 답 IDENTITY 는 DB가 INSERT 시점에 ID를 만들기 때문에 persist() 직후 INSERT 가 실행될 수 있고, JDBC batch insert에는 불리합니다. SEQUENCE 는 INSERT 전에 시퀀스에서 ID를 먼저 확보하므로 쓰기 지연과 batch insert를 활용하기 좋습니다. allocationSize 설정이 성능에 큰 영향을 줍니다. TABLE 은 여러 DB에서 동작하지만 키 전용 테이블을 SELECT 하고 UPDATE 해야 해서 락 경합과 왕복 비용이 생기기 쉽습니다. AUTO 는 편하지만 DB 방언, JPA provider, Hibernate 버전에 따라 실제 전략이 달라질 수 있어 운영 DB가 정해져 있다면 명시 전략이 더 예측하기 쉽습니다. 목차 한눈에 비교 시간 흐름으로 이해하기 선택 기준 매트릭스 왜 ID 생성 전략이 헷갈리는가 예제 쿼리와 실행 계획 persist와 INSERT 시점 설정 예시 SQL 로그로 확인하기 버전과 마이그레이션 포인트 한눈에 비교 생성 위치 IDENTITY 는 엔티티 테이블의 identity 컬럼, SEQUENCE 는 DB 시퀀스 객체, TABLE 은 별도 키 테이블, AUTO 는 provider의 판단을 사용합니다. ID를 아는 시점 IDENTITY 는 행을 실제로 넣은 뒤 ID를 알 수 있고, SEQUENCE 와 TABLE 은 INSERT 전에 ID를 확보할 수 있습니다. 쓰기 지연과 배치 저장 SEQUENCE 는 여러 INSERT 를 flush 시점까지 모으기 쉽지만, IDENTITY 는 ID 생성을 위해 행 삽입이 먼저 필요해 JDBC batch insert 효과가 제한됩니다. DB 의존성 MySQL 계열은 보통 IDENTITY , PostgreSQL과 Oracle은 SEQUENCE 를 고려하기 쉽습니다. TABLE 은 이식성은 좋지만 성능 비용이 큽니다. ...

JPA N+1 문제, 왜 생기고 어떻게 줄일까: fetch join과 EntityGraph 선택 기준까지

JPA N+1 문제, 왜 생기고 어떻게 줄일까: fetch join과 EntityGraph 선택 기준까지 빠른 답 EAGER 는 N+1의 해결책이 아니라 연관 조회 시점을 앞당기는 설정에 가깝다. JPQL이나 Spring Data JPA 조회 메서드가 조인을 자동 보장하지는 않는다. LAZY 는 문제를 없애는 방식이 아니라 미루는 방식이다. 목록을 읽은 뒤 연관 필드를 순회하는 순간 N+1이 다시 나타날 수 있다. 목록 조회 최적화는 fetch join , @EntityGraph , 배치 로딩( @BatchSize , hibernate.default_batch_fetch_size )을 조회 형태와 페이징 요구사항에 맞춰 나눠 쓰는 편이 낫다. 최적화 여부는 SQL 로그, 바인드 값, 쿼리 수, 실행 계획까지 같이 봐야 판단할 수 있다. 목차 시간 흐름으로 이해하기 흐름으로 보기 패치가 아니라 fetch 전략이다 N+1이 생기는 구조를 쿼리 관점에서 보기 LAZY와 EAGER는 왜 둘 다 N+1에서 안전하지 않은가 findAll 호출 뒤에 실제 SQL이 어떻게 늘어나는가 실행 계획과 인덱스로 보면 왜 더 느려지는가 fetch join, EntityGraph, 배치 로딩은 어떻게 나눠 쓰나 설정과 검증 예시 자주 부딪히는 함정과 현재 기준 버전 차이 시간 흐름으로 이해하기 T1 목록 조회 시작 → T2 루트 쿼리 실행 → T3 연관 로딩 대기 → T4 연관 필드 접근 → T5 추가 SQL 반복 Post 목록 API는 대개 루트 엔티티만 읽는 SQL로 시작한다. 문제는 그다음 시점이다. DTO 매핑이나 JSON 직렬화에서 post.getAuthor().getName() 같은 코드가 실행되면, 그 순간 연관 엔티티 초기화가 시작되고 결과 건수만큼 비슷한 SQL이 반복될 수 있다. 흐름으로 보기 흐름 다이어그램 N+1은 "첫 쿼리 하나가 느린 문제"라기보다 "첫 쿼리 뒤에 반복 SQL이 따라붙는 구조"에 가...

JPA EntityManager란 무엇인가: 영속성 컨텍스트와 엔티티 상태를 실무 흐름으로 이해하기

JPA EntityManager란 무엇인가: 영속성 컨텍스트와 엔티티 상태를 실무 흐름으로 이해하기 빠른 답 EntityManager의 핵심 역할은 DB에 바로 쓰는 것이 아니라 영속성 컨텍스트를 통해 엔티티 상태를 관리하는 데 있다. persist를 호출해도 INSERT가 즉시 나가지 않을 수 있으며, 실제 SQL 시점은 flush와 commit에 달려 있다. 1차 캐시와 변경 감지는 영속 상태의 엔티티에서만 기대한 대로 동작한다. merge, detach, clear를 무심코 쓰면 예상하지 못한 UPDATE 누락이나 중복 조회가 생길 수 있다. 목차 흐름으로 보기 왜 EntityManager를 영속성 컨텍스트로 이해해야 할까 영속성 컨텍스트와 EntityManager는 어떤 관계일까 엔티티 상태는 어떻게 바뀔까 Spring Boot에서 EntityManager와 트랜잭션은 어떻게 묶일까 persist, find, detach, remove, flush를 코드로 따라가 보기 merge가 특히 헷갈리는 이유 SQL 로그로 보면 동작이 더 선명해진다 실무에서 자주 놓치는 주의점 흐름으로 보기 실무에서는 이 여섯 단계를 머릿속에 두는 것만으로도 JPA 동작을 훨씬 예측하기 쉬워집니다. 객체를 만들었다고 바로 DB와 연결되는 것이 아니고, persist() 로 영속성 컨텍스트에 올린 뒤에야 관리가 시작됩니다. 이후 필드 변경은 메모리 안에서 추적되다가 flush() 나 commit 시점에 SQL로 반영됩니다. 마지막으로 detach() 는 관리 대상에서 분리하고, remove() 는 삭제 예정 상태로 바꿉니다. 왜 EntityManager를 영속성 컨텍스트로 이해해야 할까 EntityManager 를 메서드 모음으로만 보면 persist() 는 저장, find() 는 조회, remove() 는 삭제처럼 따로따로 보입니다. 하지만 실제로는 모두 영속성 컨텍스트를 조작하는 행위입니다. 예를 들어 find() 는 단순 조회가 아닙니다. 먼저 1차...

application.yml

application.yml 빠른 답 운영 환경에서는 보통 none 또는 validate만 두고 스키마 변경은 Flyway나 Liquibase로 관리합니다. update는 개발 속도를 높이지만 운영 DB에는 예측하기 어려운 변경을 만들 수 있어 신중해야 합니다. create와 create-drop은 기존 데이터를 지우므로 로컬 실험이나 테스트 환경 전용으로 보는 편이 안전합니다. 프로필별 설정을 분리하지 않으면 개발용 ddl-auto가 운영까지 들어가는 실수가 생길 수 있습니다. spring: jpa: open-in-view: false hibernate: ddl-auto: validate 목차 application-local.yml application-test.yml application-prod.yml 흔한 실수 application-local.yml spring: jpa: hibernate: ddl-auto: update application-test.yml spring: jpa: hibernate: ddl-auto: create-drop application-prod.yml spring: jpa: hibernate: ddl-auto: validate 이렇게 두면 프로필이 잘못 붙더라도 기본값이 최소한 안전한 쪽에 가깝습니다. 팀에 따라 운영은 `none`, 스테이징은 `validate`로 더 분리하기도 합니다. 중요한 것은 “명시적으로 적는다”는 점입니다. 기본값 추정에 기대면 임베디드 DB, Flyway 감지 여부, 테스트 환경 구성에 따라 생각과 다른 동작이 나올 수 있습니다. 엔티티 변경이 실제로 어떻게 보이는지는 짧은 예제가 가장 빠릅니다. java @Entity @Table(name = "member") public class Member { @Id @GeneratedValue(strategy = Ge...

JPA와 Hibernate, Spring Data JPA를 헷갈리지 않게 구분하는 방법

JPA와 Hibernate, Spring Data JPA를 헷갈리지 않게 구분하는 방법 빠른 답 JPA는 표준 명세이고, Hibernate는 그 명세를 구현하는 ORM 엔진이다. Spring Data JPA는 JPA 위에 Repository 추상화를 얹어 반복 코드를 줄여준다. 현업의 흔한 조합은 Spring Data JPA + Hibernate이지만, 세 개는 같은 계층의 기술이 아니다. 성능이나 쿼리 문제를 볼 때는 Repository 이름보다 결국 Hibernate가 만든 SQL과 JPA 설정을 함께 봐야 한다. 초안을 발행용 본문으로 재구성하되, 버전 민감한 부분은 공식 문서 기준으로 먼저 확인하겠습니다. 이후 비교 축, 실행 흐름, 현재 기준 migration 포인트가 초반부터 보이도록 문단과 예시를 정리하겠습니다.# JPA와 Hibernate, Spring Data JPA를 헷갈리지 않게 구분하는 방법 목차 한눈에 비교 흐름으로 보기 왜 셋이 늘 한 묶음처럼 보일까 JPA는 명세이고, Hibernate는 구현체이고, Spring Data JPA는 추상화다 코드로 보는 역할 차이 실무에서는 어떤 조합으로 쓰게 될까 지금 기준에서 주의할 버전 포인트 Spring Data JPA를 써도 Hibernate를 알아야 하는 순간 언제 무엇을 기준으로 선택하면 될까 한눈에 비교 JPA: 무엇을 표준화하나가 핵심이다. EntityManager , 엔티티 매핑, JPQL, 영속성 컨텍스트, 엔티티 생명주기 같은 공통 규칙을 정의한다. Hibernate: 어떻게 실행하나가 핵심이다. JPA 규약을 받아 SQL을 만들고, DB dialect를 적용하고, 캐시와 배치, flush, proxy, lazy loading을 처리한다. Spring Data JPA: 어떻게 덜 쓰고 빨리 만들까가 핵심이다. JpaRepository , 메서드 이름 기반 쿼리, @Query , 페이지네이션, 정렬, Specification 같은 생산성 기능을 제공한다. ...