🔍 변경 감지 (Dirty Checking)
- 영속 상태의 엔티티를 수정하면 JPA가 처음 조회했을 때의 상태(스냅샷) 와 비교하여
변경된 필드를 자동으로 감지하고 트랜잭션 커밋 시UPDATESQL을 실행
✅ 동작 원리
em.find() → DB에서 조회 후 스냅샷 저장
Java 코드에서 필드 변경
transaction.commit() 시
UPDATE SQL 자동 실행📌 예시 코드 요약
Tutor tutor = em.find(Tutor.class, 1L); // DB 조회 및 스냅샷 저장
tutor.setName("수정된 이름"); // 필드 변경
// em.persist(tutor); ❌ 필요 없음
transaction.commit(); // UPDATE SQL 자동 실행
🧠 중요한 점
em.persist()는 새 엔티티 저장 시 사용하는 메서드Java Collection처럼 사용 가능📦 내부 구조
📸 스냅샷(Snapshot)
: Entity의 초기 상태 복사본

값을 조회한 최초 시점의 상태를 임시로 저장

🔄 변경 비교
: 커밋 시점에 현재 값과 스냅샷 비교 후 SQL 생성
if (!snapshot.equals(current)) {
// UPDATE SQL 생성
}
🗑️ 삭제도 동일 구조
em.remove(tutor); // 삭제 예약
transaction.commit(); // 이 시점에 DELETE SQL 실행
💡 삭제도 커밋 시점에 SQL이 실행됨
💨 flush란?
- 영속성 컨텍스트에서 관리 중인 변경 내용을 데이터베이스에 동기화하는 작업
- SQL을 실제 DB로 반영하는 시점을 조절
⏱️ flush 호출 시점
| 방식 | 설명 |
|---|---|
| 자동 | transaction.commit() 시 자동 호출됨 |
| 수동 | em.flush()로 원하는 시점에 직접 호출 가능 |
📌 예시 코드 요약
Tutor tutor = new Tutor(1L, "wonuk", 100);
em.persist(tutor);
em.flush(); // INSERT SQL 즉시 실행
transaction.commit(); // INSERT 이미 실행됨, 추가 SQL 없음
🔄 flush vs commit
| 구분 | flush | commit |
|---|---|---|
| SQL 실행 여부 | 변경 내용 DB 반영 | flush 포함 + 트랜잭션 종료 |
| 트랜잭션 종료 여부 | ❌ | ✅ |
| 수동 호출 가능 | ✅ | ❌ (자동) |
🧠 요약 정리
| 항목 | 개념 | 동작 시점 | 비고 |
|---|---|---|---|
| 🧾 변경 감지 | Entity 수정 자동 추적 | commit() | UPDATE SQL 자동 생성 |
| 📸 스냅샷 | 최초 조회 상태 복사본 | find() 직후 | 비교 기준 |
| 💨 flush | 변경 내용 즉시 반영 | flush() 또는 commit() | 트랜잭션은 유지 |
| 🧹 remove | 삭제 예약 | remove() 후 commit() | DELETE SQL 실행됨 |