1️⃣ 엔티티 생명주기란?
JPA에서 엔티티(Entity) 는 단순한 자바 객체(POJO)가 아니다.
EntityManager가 관리하는 “영속성 컨텍스트(Persistence Context)” 안에서 상태를 가지는 객체로 존재한다.
즉, 엔티티는 아래와 같은 상태 변화(생명주기, Lifecycle) 를 거친다.

🪄 엔티티의 4가지 상태
| 상태 | 설명 | 예시 |
| 비영속 (Transient) | 아직 JPA가 모르는 단순한 객체 | new Member("홍길동") |
| 영속 (Persistent) | EntityManager에 의해 관리 중 | em.persist(member) 이후 |
| 준영속 (Detached) | 관리에서 벗어난 상태 | em.detach(member) |
| 삭제 (Removed) | 삭제 예약 상태 | em.remove(member) |
2️⃣ 생명주기 이벤트 콜백 (Lifecycle Callback)
JPA는 엔티티가 위 상태들을 오가며
“저장되기 전”, “수정되기 전”, “삭제되기 전” 등 특정 시점에
자동으로 호출되는 이벤트 콜백 메서드를 제공한다.
이게 바로 @PrePersist, @PostPersist, @PreUpdate, @PostUpdate 등의 Lifecycle Callback 어노테이션이다.
3️⃣ 주요 콜백 어노테이션 정리
| 어노테이션 | 동작 시점 | 설명 |
| @PrePersist | persist() 실행 직전 | INSERT SQL 실행 전, 최초 저장 전에 호출 |
| @PostPersist | INSERT SQL 실행 후 | DB 반영 직후 호출 |
| @PreUpdate | UPDATE SQL 실행 전 | 엔티티가 수정되어 flush될 때 실행 |
| @PostUpdate | UPDATE SQL 실행 후 | 수정 완료 직후 호출 |
| @PreRemove | 삭제 직전 | delete 전 호출 |
| @PostRemove | 삭제 직후 | delete 후 호출 |
| @PostLoad | 조회 직후 | SELECT 후 엔티티가 생성될 때 호출 |
4️⃣ 예시 코드 — @PrePersist, @PreUpdate
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
@PrePersist
public void prePersist() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
System.out.println("[PrePersist] 저장 전: createdAt=" + createdAt);
}
@PreUpdate
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
System.out.println("[PreUpdate] 수정 전: updatedAt=" + updatedAt);
}
}
5️⃣ AuditingEntityListener와의 관계
@EnableJpaAuditing + @EntityListeners(AuditingEntityListener.class)를 활성화하면
스프링이 내부적으로 @PrePersist, @PreUpdate를 감지해서
@CreatedDate, @LastModifiedDate 같은 필드를 자동으로 세팅하게 된다.
즉, 우리가 직접 prePersist() 안에서 LocalDateTime.now()를 넣을 필요가 없다.
'Spring > JPA' 카테고리의 다른 글
| [JPA] BaseEntity로 공통 엔티티 속성 추상화하기 (0) | 2025.11.06 |
|---|