본문 바로가기

Spring Boot/Spring Data JPA

JPA) JPA Auditing으로 자동화

JPA Auditing 이란

Spring boot JPA 에서 지원하는 기능 중 하나인 Auditing은 뜻 그대로

엔티티가 생성되고 수정되는 시점을 감시하여 생성일, 생성자, 수정일, 수정자 를 자동으로 기록할 수 있다.

생성일 ~ 수정자는 모든 엔티티들이 공통적으로 가지고 있는 컬럼이므로

중복되는 코드를 줄이기 위해 BaseEntity 로 분리하여 여러 방법으로 Auditing을 구현해보자.

 

 

 

BaseEntity

 

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity implements Serializable {

    @CreatedDate
    @Column(updatable = false, insertable = true)
    private LocalDateTime crtDt;

    @LastModifiedDate
    @Column(updatable = true, insertable = true)
    private LocalDateTime mdfDt;
    
    @PrePersist
    public void prePersist() {
        // save 발생 직전 작업 수행
        crtDt = LocalDateTime.now();
        mdfDt = LocalDateTime.now();
    }
    
    @PreUpdate
    public void preUpdate) {
        mdfDt = LocalDateTime.now();
    }
}

 

@MappedSuperClass

JPA에서 entity간 공통으로 사용되는 매핑 정보를 정의하기 위해 사용하는 어노테이션이다.

타 entity에서 base entity를 상속받아 속성만 사용할 수 있도록 도와준다.

 

@Column

  1. update able 속성은 update 쿼리에서의 동작 여부를 설정할 수 있다.
  2. insert able 속성은 insert 쿼리 즉 최초 등록 여부를 설정할 수 있다.

insertable, udpateable 두 값의 초기값은 true

 

 

@PrePersist 어노테이션은 JPA entity 라이프 사이클의 콜백을 조종할 수 있게 하는 어노테이션이다.

(JPA에서 제공하는 어노테이션)

    //base entity
    @PrePersist
    public void prePersist(User user) {
        // save 발생 직전 작업 수행
        crtDt = LocalDateTime.now();
    }

 

 

라이프 사이클 어노테이션을 사용해 저장 시에 정의한 메소드를 호출시킬 수 있다.

@PrePersist 이외에도 아래와 같은 다양한 라이프 사이클 어노테이션이 존재한다

https://www.baeldung.com/jpa-entity-lifecycle-events

 

 

 

Spring data jpa의 Auditing

위에서의 audit 기능은 순수 JPA가 지원하는 기능이다. 아래 스프링 데이터에서 지원하는 어노테이션은

조금 더 편리하고 자동화된 audit 기능을 제공한다.

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity implements Serializable {

    @CreatedDate
    @Column(updatable = false, insertable = true)
    private LocalDateTime crtDt;

    @CreatedBy
    @Column(updatable = false, insertable = true)
    private String crtrUid;

    @LastModifiedDate
    @Column(updatable = true, insertable = true)
    private LocalDateTime mdfDt;

    @LastModifiedBy
    @Column(updatable = true, insertable = true)
    private String mdfrUid;
}

 

@EntityListeners(AuditingEntityListner.class) 

spring data jpa가 지원하는 이벤트 리스너.

이 리스너는 Audit 컬럼에 이벤트(등록, 수정)가 발생할 때 마다 Audit가 반영될 준비를 해준다.

 

@CreatedDate (org.springframework.data)

데이터 생성 날짜 자동 저장 어노테이션

 

@LastModifiedDate (org.springframework.data)

데이터 수정 날짜 자동 저장 어노테이션

 

@CreatedBy (org.springframework.data)

데이터 생성자 자동 저장 어노테이션

 

@LastModifiedBy (org.springframework.data)

데이터 수정자 자동 저장 어노테이션

 

각각의 어노테이션을 적용하면 base entity 를 상속받아 사용하는 자식 클래스에서 정의한 audit기능을 발생시킨다.

CreatedBy, LastModifiedBy 에 필요한 값을 넣어주기 위해서 아래와 같은 작업이 필요하다

 

 

 

@EnableJpaAuditing

spring security 를 적용하고있으면 SecurityContextHolder의 인증정보를 생성자와 수정자 컬럼에 넣어줄 수 있다.

@Configuration
@EnableJpaAuditing
public class JpaAuditConfig {
    @Bean
    public AuditorAware<String> auditorProvider(){
        return new AuditorAware();
    }
}

 

@EnableJpaAuditing 를 config에 선언, java config에 등록해주고

생성자와 수정자에 들어갈 내용을 지정해주기 위해 재정의를 해준다

 

public class AuditorAware implements AuditorAware<String> {
    @Override
    public String getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null
        }
        return (String) authentication.getPrincipal();
    }
}

 

getCurrentAuditor 메소드에서 상황에 맞게 생성자, 수정자에 들어갈 내용을 재정의한다.

위 코드에서는 스프링 시큐리티의 인증 정보에서 필요한 사용자 정보를(principal) 추출하여 생성,수정자를 할당한다

 

 

 


https://ojt90902.tistory.com/711

https://www.baeldung.com/jpa-entity-lifecycle-events

https://bepoz-study-diary.tistory.com/384