[JPA] 엔티티 생명주기 완전 정리 — persist, detach, merge, remove

cheetah_hong·2025년 10월 24일

JPA

목록 보기
3/3
post-thumbnail

이전에 작성했던 영속성 컨텍스트, 더티 체킹과 이어지는 개념입니다.
트랜잭션 내에서 엔티티가 어떻게 관리되는지 이해하면 혼란이 줄어듭니다.


엔티티 상태 4가지

JPA에서는 엔티티가 트랜잭션과 영속성 컨텍스트 안에서 다음 4가지 상태를 가집니다.

상태의미상태 전이 메서드DB 반영 여부
new / transient아직 DB와 연결되지 않은 새 객체persist()
managed / persistent영속성 컨텍스트에 의해 관리되는 상태-flush/commit 시 변경 감지 후 DB 반영
detached / 준영속영속성 컨텍스트에서 분리된 상태merge()기존 엔티티와 병합 시 반영
removed삭제 예정 상태remove()flush/commit 시 DELETE 실행

🔄 상태 전이 예시

@Transactional
public void jpaLifecycle(EntityManager em) {

    //  new / transient
    Member m = new Member("CHEETAH"); // 생성 직후
    System.out.println("new? " + em.contains(m)); // false

    //  persist -> managed
    em.persist(m);
    System.out.println("managed? " + em.contains(m)); // true
    em.flush(); // INSERT SQL 발생

    //  detach -> detached
    em.detach(m);
    System.out.println("detached? " + !em.contains(m)); // true
    m.setName("WONT_SAVE"); // 아직 DB 반영 X

    //  merge -> managed 재진입
    Member merged = em.merge(m);
    merged.setName("OK"); // DB에 반영
    // flush 시 UPDATE SQL 발생

    // remove -> removed
    em.remove(merged);
    // flush 시 DELETE SQL 발생
}

로그

Hibernate: insert into member (name, id) values (?, ?)
Hibernate: update member set name=? where id=?
Hibernate: delete from member where id=?
  • New → Managed: persist() 호출

  • Managed → Detached: detach() 또는 clear()

  • Detached → Managed: merge()

  • Managed → Removed: remove()

  • flush/commit 시점에 실제 SQL 실행

✅ 혼동 포인트

1) detach 된 객체를 수정하면 DB에 반영되지 않음

Member m = em.find(Member.class, id);
em.detach(m);
m.setName("NO UPDATE"); // UPDATE X

2) merge 후 반환값을 사용해야 안전

Member detached = new Member("OLD");
Member managed = em.merge(detached);
managed.setName("NEW"); // OK
detached.setName("FAIL"); // DB X

3) remove와 flush

remove() 호출 후 flush 또는 commit 시 DELETE 발생

remove 전에도 setName 등 수정 가능 → flush 시 DELETE 우선

4) 트랜잭션과 상태 관계

트랜잭션이 끝나면 managed 상태 엔티티는 자동으로 detach

따라서 트랜잭션 범위를 잘 정의해야 안전

✔️ 체크리스트

엔티티를 DB에 처음 저장: persist()

영속성 컨텍스트에서 제외: detach(); / clear()

detached 엔티티 DB 반영: merge() → 반환값 사용

삭제: remove() -> flush/commit 시 DELETE

트랜잭션 범위 내에서 상태 변화 이해 필수

✅ 요약

  • JPA 엔티티는 4가지 상태(New, Managed, Detached, Removed)로 구분되며

  • 상태 전이를 이해하면 save(), merge(), remove() 동작의 차이를 명확히 알 수 있습니다.

  • 영속성 컨텍스트 + 더티 체킹 + 엔티티 상태를 합쳐서 이해해야 실무에서 혼란을 예방합니다.

  • 트랜잭션 범위, flush/commit, detach/merge 전략을 활용하면 안전하게 DB를 조작할 수 있어요.

profile
치타는 지금 웃고있다 🐆

0개의 댓글