JPA Auditing - 생성 / 수정 시간 자동관리

StrayCat·2026년 2월 15일

왜 필요한가?

게시글, 댓글, 메모 등 거의 모든 엔티티에는 생성 시간수정 시간이 필요합니다. 그런데 매번 엔티티마다 이 필드를 선언하고, save() 할 때마다 LocalDateTime.now()를 직접 넣어주는 건 반복적이고 비효율적입니다.

Spring Data JPA는 이 문제를 해결하기 위해 JPA Auditing 기능을 제공합니다. 엔티티가 저장되거나 수정될 때 시간 값을 자동으로 채워줍니다.


구현 구조 (3단계)

1단계: Timestamped 추상 클래스 생성

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Timestamped {

    @CreatedDate
    @Column(updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime modifiedAt;
}

2단계: Application 클래스에 Auditing 활성화

@EnableJpaAuditing  // 이걸 빼먹으면 시간이 null로 들어갑니다
@SpringBootApplication
public class MemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MemoApplication.class, args);
    }
}

3단계: 엔티티에서 상속

@Entity
public class Memo extends Timestamped {
    // createdAt, modifiedAt 컬럼이 자동으로 포함됩니다
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String contents;
    // ...
}

핵심 어노테이션 정리

어노테이션역할
@MappedSuperclass이 클래스의 필드를 상속받는 엔티티의 컬럼으로 인식시킴. Timestamped 자체는 테이블이 생기지 않습니다.
@EntityListeners(AuditingEntityListener.class)Auditing 기능(시간 자동 주입)을 해당 클래스에 연결합니다.
@CreatedDate엔티티가 최초 저장될 때 시간을 자동 기록합니다.
@LastModifiedDate엔티티가 수정될 때마다 시간을 자동 갱신합니다.
@Temporal(TemporalType.TIMESTAMP)DB에 날짜+시간 형태(2026-01-01 20:21:23.454)로 저장합니다. (DATE, TIME도 가능)
@EnableJpaAuditingSpringBoot에게 JPA Auditing 기능을 사용하겠다고 알려줍니다.

왜 abstract 클래스인가?

Timestamped 자체를 new Timestamped()로 생성할 일은 없습니다. 오직 다른 엔티티가 상속받아 사용하는 용도이므로 abstract로 선언하는 것이 적절합니다.


@Temporal 참고사항

@Temporal은 원래 java.util.Datejava.util.Calendar 타입을 매핑할 때 필수였습니다. LocalDateTime을 사용하는 경우 Hibernate가 자동으로 타입을 인식하기 때문에 생략해도 동작합니다. 다만 명시적으로 적어두면 의도가 분명해지는 장점이 있어서, 붙여두는 것이 좋은 습관입니다.


동작 흐름 요약

Memo 저장(persist) → AuditingEntityListener 동작
                     → createdAt에 현재 시간 자동 세팅
                     → modifiedAt에 현재 시간 자동 세팅

Memo 수정(dirty checking) → AuditingEntityListener 동작
                           → createdAt은 updatable=false이므로 변경 안 됨
                           → modifiedAt만 현재 시간으로 갱신

이렇게 한 번 세팅해두면, 이후 만드는 모든 엔티티에서 extends Timestamped만 붙이면 생성/수정 시간이 자동 관리됩니다. 실무에서도 거의 모든 프로젝트에서 이 패턴을 사용합니다.

profile
알면 좋은 것보단 잊어버리기 싫은 것들을 기록합니다.

0개의 댓글