Contents
1. 하이버네이트(Hibernate) 기술 (필기 위주)0️⃣ 필기1️⃣ Hibernate란 무엇인가?2️⃣ DB 세계 vs Java 세계의 차이3️⃣ 객체 연관관계 vs 테이블 관계4️⃣ Persist Context (영속성 컨텍스트)5️⃣ em.find() 동작 과정6️⃣ em.clear()7️⃣ em.flush()8️⃣ em.remove() (삭제)9️⃣ Update (변경 감지, Dirty Checking)🔟 Hibernate의 핵심 장점 요약2. Hibernate에서 꼭 알아야 할 핵심 추가 개념1️⃣ 엔티티 생명주기 (매우 중요)2️⃣ 지연 로딩(LAZY) vs 즉시 로딩(EAGER) ⭐⭐⭐3️⃣ 프록시(Proxy) 개념 (LAZY의 핵심 원리)4️⃣ 트랜잭션은 선택이 아니라 필수5️⃣ N+1 문제 (면접 단골)6️⃣ Cascade (전이) 개념7️⃣ 연관 관계의 주인 (외래키 관리 주체)8️⃣ flush vs commit (차이 정확히)9️⃣ JPQL ≠ SQL🔟 Hibernate 한 줄 정리1. 하이버네이트(Hibernate) 기술 (필기 위주)
0️⃣ 필기

1️⃣ Hibernate란 무엇인가?
1) 개념
DB(테이블의 세계)와 Java(객체의 세계) 라는 서로 다른 두 세계의 데이터를 같은 시점처럼 일치시켜 주는 ORM(Object–Relational Mapping) 기술
2) 핵심 목적
“객체 중심으로 개발하면서도 DB와의 불일치를 최소화”
2️⃣ DB 세계 vs Java 세계의 차이
1) DB (테이블 중심)
- 테이블, 컬럼, 행(Row)
- 관계 표현: 외래키(FK)
- 정규화된 구조
- 상속 개념 ❌
2) Java (객체 중심)
- 객체, 필드, 메서드
- 상속, 다형성
- 객체 참조 (
has-a)
- 컬렉션(List, Set 등)
➡️ 이 구조적 차이(Gap) 를 해결하는 것이 Hibernate의 역할
3️⃣ 객체 연관관계 vs 테이블 관계
1) ❌ 잘못된 방식 (그림의 X 표시)
햄버거세트 테이블
- 햄버거
- 콜라
- 감자- 테이블을 객체 구조에 맞추면
- DB가 객체에 종속됨 → ❌
2) ✅ Hibernate가 권장하는 방식
Hamburger Table
Cola Table
Potato Table- DB는 DB답게 (정규화, FK)
- Java는 Java답게 (객체 참조)
class HamburgerSet {
Hamburger hamburger;
Cola cola;
Potato potato;
}➡ Hibernate가 FK ↔ 객체 참조를 자동으로 매핑
4️⃣ Persist Context (영속성 컨텍스트)
1) 정의
EntityManager가 관리하는 엔티티의 1차 캐시 공간
- 엔티티의 생명주기 관리
- 변경 감지 (Dirty Checking)
- 쓰기 지연 (Flush 시 SQL 실행)
엔티티(Entity)란?
DB의 한 “테이블”을 Java에서 “객체”로 표현한 것
5️⃣ em.find() 동작 과정
1) 첫 번째 find
em.find(Board.class, 1L);- Persist Context에 있는지 확인
- ❌ 없으면 → DB에 SELECT
- 조회 결과를 Persist Context에 저장
- 엔티티 반환
2) 두 번째 find (같은 ID)
em.find(Board.class, 1L);- Persist Context에 이미 있음
- DB 조회 없이 바로 반환
➡ 1차 캐시 효과
6️⃣ em.clear()
em.clear();
- Persist Context 초기화
- 관리 중이던 엔티티 전부 제거
➡️ 이후
find() 호출 시 → 무조건 DB 재조회7️⃣ em.flush()
1) 역할
- Persist Context의 변경 내용을 DB에 반영(SQL 실행)
2) 주의
- flush = commit 아님
- 단지 SQL을 DB에 보내는 시점
Persist Context 변경
↓
flush()
↓
insert / update / delete SQL 실행8️⃣ em.remove() (삭제)
1) ❌ 안 되는 경우
Board board = new Board(); // new 객체
em.remove(board); // ❌- Persist Context에서 관리되지 않는 객체(비영속)
2) ✅ 가능한 경우
Board board = em.find(Board.class, 1L);
em.remove(board); // ⭕- 관리 상태(영속 상태) 엔티티만 삭제 가능
- 실제 DB 삭제는 flush 시점
9️⃣ Update (변경 감지, Dirty Checking)
Board board = em.find(Board.class, 1L);
board.setTitle("변경된 제목");- update 쿼리 작성 ❌
- flush 시 Hibernate가
- 이전 상태 vs 현재 상태 비교
- 변경 감지 → update SQL 자동 생성
엔티티 상태 변경
↓
Hibernate가 감지
↓
update SQL 생성
↓
flush() 시 실행🔟 Hibernate의 핵심 장점 요약
기능 | 설명 |
ORM | 객체 ↔ 테이블 자동 매핑 |
1차 캐시 | 같은 엔티티 DB 재조회 방지 |
변경 감지 | setter만 호출해도 update |
쓰기 지연 | flush 시점에 SQL 실행 |
객체 중심 | SQL보다 비즈니스 로직 집중 |
2. Hibernate에서 꼭 알아야 할 핵심 추가 개념
1️⃣ 엔티티 생명주기 (매우 중요)
Hibernate의 모든 동작은 엔티티 상태를 기준으로 설명됩니다.
1) 4가지 상태
상태 | 설명 |
비영속 (Transient) | new로 생성, DB/PC 무관 |
영속 (Persistent) | em이 관리 중 (1차 캐시) |
준영속 (Detached) | PC에서 분리됨 |
삭제 (Removed) | 삭제 예약 상태 |
Board b = new Board(); // 비영속
em.persist(b); // 영속
em.detach(b); // 준영속
em.remove(b); // 삭제➡️ remove / dirty checking / cache / flush 전부 이 개념에서 출발
2️⃣ 지연 로딩(LAZY) vs 즉시 로딩(EAGER) ⭐⭐⭐
1) 기본 원칙 (시험·실무 공통)
모든 연관 관계는 LAZY가 기본
@ManyToOne(fetch = FetchType.LAZY)
private Member member;2) 차이
방식 | 특징 |
EAGER | 엔티티 조회 시 즉시 조인 |
LAZY | 실제 접근 시 쿼리 실행 |
board.getMember().getName(); // 이 시점에 SELECT⚠️ EAGER는 N+1 문제의 주범
3️⃣ 프록시(Proxy) 개념 (LAZY의 핵심 원리)
LAZY는 프록시 객체로 구현됨.
MemberProxy (가짜 객체) ↓ 실제 접근 시 Member (진짜 객체)
1) 프록시 특징
- 클래스 상속
- 초기화 전까지 DB 접근 ❌
- 영속성 컨텍스트 없으면 ❌
⚠️ 자주 나오는 에러
LazyInitializationException
➡ 세션 종료 후 프록시 접근 시 발생
4️⃣ 트랜잭션은 선택이 아니라 필수
Hibernate에서 트랜잭션 없는 변경은 없다
1) 중요한 사실
- flush는 트랜잭션 안에서만 의미 있음
- 변경 감지는 트랜잭션 커밋 시점에 작동
@Transactional
public void update() {
Board b = em.find(...);
b.setTitle("변경");
}➡
@Transactional 없으면 update 안 됨 / 예외 발생5️⃣ N+1 문제 (면접 단골)
1) 문제 상황
List<Board> boards = boardRepository.findAll();
- Board 조회 1번
- 각 Board의 연관 엔티티 조회 N번
➡ 총 1 + N 쿼리
2) 해결 방법
- fetch join
- @EntityGraph
- 배치 사이즈
select b from Board b join fetch b.member6️⃣ Cascade (전이) 개념
@OneToMany(cascade = CascadeType.ALL)1) 의미
부모 엔티티의 생명주기를 자식에게 전파
옵션 | 의미 |
PERSIST | 저장 전파 |
REMOVE | 삭제 전파 |
ALL | 전부 |
❗ 실무 주의
- 연관관계 전체에 ALL 남용 ❌
- 라이프사이클이 완전히 종속될 때만 사용
7️⃣ 연관 관계의 주인 (외래키 관리 주체)
1) 핵심 규칙
FK를 가진 쪽이 연관관계의 주인
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;- 주인만이 DB 반영
- mappedBy는 읽기 전용
❗ 양방향 관계에서 한 쪽만 관리
8️⃣ flush vs commit (차이 정확히)
구분 | flush | commit |
SQL 실행 | ⭕ | ⭕ |
트랜잭션 종료 | ❌ | ⭕ |
롤백 가능 | ⭕ | ❌ |
➡ commit = flush + 트랜잭션 종료
9️⃣ JPQL ≠ SQL
- JPQL은 객체 대상
- SQL은 테이블 대상
select b from Board b❌
select * from board➡ Hibernate가 JPQL → SQL 변환
🔟 Hibernate 한 줄 정리
Hibernate는 영속성 컨텍스트를 중심으로 객체의 상태 변화를 감지하여 SQL을 자동 생성·관리하는 ORM 프레임워크
Share article