Yebali

Spring Data JPA의 Auditing 기능 본문

Spring

Spring Data JPA의 Auditing 기능

예발이 2021. 10. 11. 21:51

Auditing이란?

개발을 하다 보면 DB 테이블마다 꼭 들어가는 4가지 값이 있다.
등록일, 수정일, 등록자, 수정자 이다.
Spring Data JPA에는 이 4가지를 자동으로 관리해주는 기능이 있다

 

순수한 JPA

순수한 JPA를 사용하여 등록일과 수정일을 관리하는 방법은 아래와 같다.

BaseEntity Class

@PrePersist, @PreUpdate 애너테이션을 이용해 자동으로 createdData와 udpatedDate를 관리하게 한다.

@MappedSuperclass
@Getter
public class JpaBaseEntity {
    
    @Column(updatable = false)
    private LocalDateTime createdDate; //등록일
    
    private LocalDateTime updatedDate; //수정일
    
    @PrePersist
    public void prePersist() {
        LocalDateTime now = LocalDateTime.now();
        createdDate = now;
        updatedDate = now;
    }
    
    @PreUpdate
    public void preUpdate() {
        updatedDate = LocalDateTime.now();
    }
}

@PrePersist, @PreUpdate외에도 @PostPersist, @PostUpdate 애너테이션을 사용할 수도 있다.

BaseEntity 적용

Member Entity에 아래와 같이 적용할 수 있다.
이후에 Member Entity를 등록/수정할 때마다 자동으로 createdData와 udpatedDate가 관리된다.

public class Member extends JpaBaseEntity {}

Spring Data JPA

Auditing 기능을 사용하기 위한 설정 두 가지가 있다.

  1. @EnableJpaAuditing 애너테이션을 스프링 부터 설정 클래스에 적용해야 한다.
  2. @EntityListeners(AuditingEntityListener.class)를 Entity에 적용해야 한다.

BaseEntity

Spring Data JPA는 Auditing을 위해 BaseEntity에 아래 4개의 애너테이션을 사용한다.

  • @CreatedData
  • @LastModifiedDate
  • @CreateBy
  • @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를 Spring Bean으로 등록해야 한다.

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

위 코드에서는 랜덤 값을 넣었지만 실제로는 세션, 토큰 정보 등의 사용자 정보를 받아 넣으면 된다.

참고

가끔 등록일, 수정일은 필요하지만 등록자, 수정자는 필요 없을 수 있다.
그럴 때는 BaseEntity를 분리하고 원하는 타입만 선택해서 상속하면 된다.

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;
}

저장 시점에서는 등록일==수정일, 등록자==수정자이다. 데이터 중복 같지만 유지보수 관점에서는 이게 더 편리하다.
만약 저장시점에 등록일, 등록자만 입력하고 싶다면 @EnableJpaAuditing(modifyOnCreate = false) 옵션을 사용하면 된다.