본문 바로가기
Spring|Spring-boot/Spring-Data-JPA

Auditing

by oncerun 2022. 11. 30.
반응형

 

우리 실무 테이블엔 등록일, 수정일이 거의 무조건적으로 존재한다. 

정말 이는 필요 없어 보이지만 운영에서 매우 잘 사용하는 칼럼 중 하나이다.

 

  • 등록일
  • 수정일
  • 등록자
  • 수정자

 

평균적으로 위 컬럼들은 기본적으로 깔고 가기도 한다.

 

ORM은 기본적으로 객체를 중심적으로 본다. 이러한 공통적인 속성은 상속과 같은 개념으로 처리할 수 없을까? 

 

당연히 존재한다.

 

@MappedSuperclass
public class JpaBaseEntity {

    @Column(updatable = false, insertable = true)
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

    @PrePersist
    public void prePersist() {
        LocalDateTime now = LocalDateTime.now();
        this.createdAt = now;
        this.updatedAt = now;
    }

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

}

기본적으로 다음과 같이 사용해보자. 

 

실제 update가 되지 말아야 할 칼럼은 updateable 속성을 통해 막을 수 있다.

 

@PrePersist는 이벤트의 한 종류로 엔티티 저장 시 발생하는 이벤트이다.

 

@PreUpdate도 마찬가지로 업데이트 시 발생하는 이벤트이다.

 

 

이러한 이벤트를 활용하면 수정 시 전파되어야할 상황이나 로직을 한 곳으로 모을 수 있기에 유지보수 관점에서 편할 수 있다고 생각한다.

 

그런데 이는 JPA에서 제공해주는 어노테이션이다 패키 지명을 보면 다음과 같다.

package javax.persistence;

 

스프링 데이터 JPA는 이걸 더 깔끔하게 해결해줄 수 있다 .

 

스프링 부트 설정 클래스에 @EnableJpaAuditing을 설정해주어야 한다.

 

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

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

    @LastModifiedDate
    private LocalDateTime updatedAt;

}

 

이와 같이 매우 편리하게 어노테이션으로 설정해줄 수 있다.

 

 

그럼  생성자와 수정자는?

 

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

@LastModifiedBy
private String updatedBy;

 

해당 값을 어떻게 설정해야 할지 고민된다. 

 

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

실제로는 세션에서 꺼내거나 시큐리티를 사용한다면 시큐리티 콘텍스트에서 꺼내서 설정할 것이다.

 

실제로 등록되거나 수정될 때마다 auditorProvider를 호출해서 값을 꺼내간다.

 

@EntityListeners(AuditingEntityListener.class)

해당 설정이 귀찮으면 orm.xml 파일을 만들어서 처리하는 방법이 있는데 굳이?...

 

그 이후에는 엔티티에 상속해주자.

 

@MappedSuperclass는 실제 상속은 아니고 속성 값만 상속해주는 것이다. 

public class Member extends BaseEntity

 

실제로 테이블의 상속관계를 사용하기 위해선 @MapIds.. 뭐 해줄게 많다 이에 대해선 내일 상속 관련해서 정리해보자.

 

이로 인해 공통 관심사를 편리하게 모아서 상속으로 처리할 수 있다. 

 

 

 

반응형

'Spring|Spring-boot > Spring-Data-JPA' 카테고리의 다른 글

스프링 데이터 JPA 구현체를 알아보자.  (0) 2022.12.03
도메인 컨버터 & 페이징과 정렬  (0) 2022.12.03
Custom Repository  (0) 2022.11.30
JPA Hint & Lock  (0) 2022.11.27
@EntityGraph  (0) 2022.11.27

댓글