내일배움캠프 Spring 53일차(월) TIL - SpringDataJpa(Auditing)

Skadi·2024년 3월 12일
0

Spring Data JPA와 함께하는 Auditing

Spring Data JPA를 사용하면, 엔티티가 생성되거나 수정될 때 그 순간을 자동으로 기록할 수 있는 매우 유용한 기능인 Auditing을 활용할 수 있습니다. Auditing 기능을 사용하면, 방명록에 방문자가 자신이 방문한 날짜와 시간을 남기는 것처럼, 엔티티의 생성 시간과 마지막 수정 시간, 생성자와 수정자를 자동으로 기록할 수 있습니다.

Auditing 적용 방법

Auditing을 적용하기 위한 몇 가지 단계는 다음과 같습니다:

  1. @EnableJpaAuditing 추가하기
    메인 애플리케이션 클래스에 @EnableJpaAuditing 어노테이션을 추가하여 JPA Auditing을 활성화합니다.
@EnableJpaAuditing
@SpringBootApplication
public class Application {

}
  1. 엔티티 클래스에 @EntityListeners(AuditingEntityListener.class) 추가하기
    엔티티 클래스 또는 MappedSuperclass로 지정된 클래스에 @EntityListeners(AuditingEntityListener.class) 어노테이션을 추가하여 엔티티의 이벤트를 감시합니다.
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class TimeStamp {
    @CreatedDate
    private LocalDateTime createdAt;

    @CreatedBy
    @ManyToOne
    private User createdBy;

    @LastModifiedDate
    private LocalDateTime modifiedAt;

    @LastModifiedBy
    @ManyToOne
    private User modifiedBy;
}
  1. AuditorAware 구현체 만들기
    createdAt과 modifiedAt은 구현체 없이도 잘 작동하지만, createdBy와 modifiedBy는 구현체가 필요합니다. Spring Security의 SecurityContextHolder에서 인증 정보 안에 담긴 UserDetailsImpl을 사용하여 사용자 객체를 가져와 설정할 수 있습니다.
@Service
public class UserAuditorAware implements AuditorAware<User> {
    @Override
    public Optional<User> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        if (authentication == null || !authentication.isAuthenticated()) {
            return Optional.empty();
        }

        return Optional.of(((UserDetailsImpl) authentication.getPrincipal()).getUser());
    }
}
  1. @EnableJpaAuditing에 AuditorAware 빈 이름 설정
@EnableJpaAuditing(auditorAwareRef = "userAuditorAware")
@SpringBootApplication
public class Application {

}
  1. Auditing을 이용한 엔티티 라이프 사이클 이벤트 관리
    엔티티의 생성, 수정, 삭제 시점에 자동으로 실행되는 메소드를 통해, createdAt, modifiedAt, createdBy, modifiedBy를 관리할 수 있습니다. 이 과정은 객체가 생성될 때 자동으로 실행되는 @PostConstruct와 유사한 원리로, 엔티티 라이프 사이클 이벤트를 활용하여 구현합니다.
// Entity 내 정의
@PrePersist
public void prePersist() {
    super.updateModifiedAt();
    super.updateCreatedAt();
}

@PreUpdate
public void PreUpdate() {
    super.updateModifiedAt();
}

0개의 댓글