[스프링] 스프링 Data JPA(마지막) Auditing

2025. 8. 26. 14:25·스프링 데이터 JPA

애플리케이션에서 엔티티를 다루다 보면 등록일, 수정일은 거의 필수적으로 필요하다.
“이 데이터가 언제 만들어졌는지”, “마지막으로 누가 수정했는지”는 유지보수와 이력 관리에서 중요한 정보이기 때문이다.

 

따라서 엔티티에 기본적으로 등록일(createdDate), 수정일(lastModifiedDate), 등록자(createdBy), 수정자(lastModifiedBy) 같은 정보를 추적할 수 있어야 한다.
이를 어떻게 구현할 수 있을까?

 

1. 순수 JPA로 Auditing 구현하기

순수 JPA에서도 엔티티 생명주기 이벤트(@PrePersist, @PreUpdate)를 활용하면 간단히 등록일과 수정일을 기록할 수 있다.

@MappedSuperclass
public class JpaBaseEntity {

    @Column(updatable = false)
    private LocalDateTime createDate;
    private LocalDateTime updateDate;

    @PrePersist
    public void prePersist() {
        createDate = LocalDateTime.now();
        updateDate = LocalDateTime.now();
    }

    @PreUpdate
    public void preUpdate() {
        updateDate = LocalDateTime.now();
    }
}

이제 엔티티가 JpaBaseEntity를 상속하면 저장 시점과 수정 시점에 값이 자동으로 들어간다.

 

테스트 코드

@Test
public void jpaEventBaseEntity() throws Exception {
    //given
    Member member = new Member("member1");
    memberRepository.save(member); // @PrePersist 호출

    Thread.sleep(100);
    member.setUsername("member2");
    em.flush(); // @PreUpdate 호출
    em.clear();

    //when
    Member findMember = memberRepository.findById(member.getId()).get();

    //then
    System.out.println("createdDate = " + findMember.getCreatedDate());
    System.out.println("updatedDate = " + findMember.getUpdatedDate());
}

 

이 방식으로도 기본적인 시간 정보는 기록할 수 있다.
하지만 등록자, 수정자까지 관리하려면 코드가 점점 복잡해지고, 매번 공통 엔티티를 만들어야 한다는 불편이 있다.

 

2. 스프링 데이터 JPA Auditing

스프링 데이터 JPA는 이런 반복 작업을 간단히 처리할 수 있도록 Auditing 기능을 제공한다.

 

설정

  • 스프링 부트 메인 클래스에 @EnableJpaAuditing 추가
  • 엔티티에 @EntityListeners(AuditingEntityListener.class) 적용

 

제공 어노테이션

  • @CreatedDate → 등록일
  • @LastModifiedDate → 수정일
  • @CreatedBy → 등록자
  • @LastModifiedBy → 수정자

등록일·수정일 자동화

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity {
	
    //등록일 수정일
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
    
    //등록자 수정자
    @CreatedBy
    @Column(updatable = false)
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;
}

여기서 등록자와 수정자는 AuditorAware 빈을 통해 주입한다.

@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
    public static void main(String[] args) {
        SpringApplication.run(DataJpaApplication.class, args);
    }

    @Bean
    public AuditorAware<String> auditorProvider() {
        return () -> Optional.of(UUID.randomUUID().toString());
    }
}

실무에서는 UUID 대신 세션 정보나 스프링 시큐리티 로그인 사용자 정보를 넣어준다.

 

3. Base 클래스 분리 전략

실무에서는 대부분 등록일, 수정일은 필요하지만, 등록자, 수정자는 필요하지 않은 경우도 많다.
그래서 보통 공통 엔티티를 두 단계로 분리한다.

public class BaseTimeEntity {

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
}

public class BaseEntity extends BaseTimeEntity {

    @CreatedBy
    @Column(updatable = false)
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;
}
  • 단순히 시간만 필요한 경우: BaseTimeEntity 상속
  • 사용자까지 필요한 경우: BaseEntity 상속

 

마무리하며

엔티티에 등록일, 수정일, 등록자, 수정자를 남기는 건 선택이 아니라 사실상 필수에 가깝다.
순수 JPA로도 @PrePersist, @PreUpdate를 활용해 구현할 수 있지만,
스프링 데이터 JPA가 제공하는 Auditing 기능을 쓰면 훨씬 간결하고 직관적으로 관리할 수 있다.

 

상황에 따라 단순 시간만 기록하거나, 사용자 정보까지 추적할 수 있도록 Base 엔티티를 적절히 분리해 상속하는 게 실무에서 가장 중요하다고 전해진다. 

 

감사합니다.

 

'스프링 데이터 JPA' 카테고리의 다른 글

[스프링] 스프링 Data Jpa(7) 사용자 정의 리포지토리 구현  (1) 2025.08.26
[스프링] 스프링 Data JPA(6) @EntityGraph  (0) 2025.08.21
[스프링] 스프링 Data JPA(5) 벌크성 수정쿼리  (0) 2025.08.21
[스프링] 스프링 Data JPA(4) JPA 페이징과 정렬  (0) 2025.08.21
[스프링] 스프링 Data JPA(3) @Query, 리포지토리 메소드에 쿼리 정의하기  (0) 2025.08.21
'스프링 데이터 JPA' 카테고리의 다른 글
  • [스프링] 스프링 Data Jpa(7) 사용자 정의 리포지토리 구현
  • [스프링] 스프링 Data JPA(6) @EntityGraph
  • [스프링] 스프링 Data JPA(5) 벌크성 수정쿼리
  • [스프링] 스프링 Data JPA(4) JPA 페이징과 정렬
0kingki_
0kingki_
자바 + 스프링 웹 개발
  • 0kingki_
    0kingki_
    0kingki_
  • 전체
    오늘
    어제
    • 분류 전체보기 (134)
      • 코딩 테스트 (54)
      • 자바 (21)
      • 스프링 (27)
      • 타임리프 (16)
      • 스프링 데이터 JPA (8)
      • 최적화 (2)
      • QueryDSL (4)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    쿼리
    타임리프
    thymeleaf
    SpringDataJpa
    쿼리dsl
    예외처리
    다형성
    스프링 데이터 JPA
    컬렉션
    스프링 컨테이너
    불변객체
    LocalDateTime
    QueryDSL
    객체지향
    SOLID
    fetch join
    BFS
    예외 처리
    spring
    자바
    mvc
    스프링
    Java
    재귀
    코딩테스트
    최적화
    백준
    dfs
    JPA
    코딩 테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
0kingki_
[스프링] 스프링 Data JPA(마지막) Auditing
상단으로

티스토리툴바