공부해봅시당

[Spring] @EnableJpaAuditing 본문

STUDY/Spring

[Spring] @EnableJpaAuditing

tngus 2024. 2. 22. 07:41

@EnableJpaAuditing

스프링 데이터 JPA를 사용하는 애플리케이션에서

엔티티의 생성, 수정 시간 등을 자동으로 관리할 수 있도록 하는 애너테이션

 

이 애너테이션을 사용하면, 엔티티가 데이터베이스에 저장되거나 업데이트될 때 자동으로 날짜와 시간 필드를 채워주는 감사 기능을 활성화할 수 있음

이를 통해 개발자는 엔티티의 생명주기 내내 발생하는 변경사항을 추적하는 코드를 직접 구현할 필요가 없어짐

 

따라서 @EnableJpaAuditing 어노테이션이 없을 경우 @CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy와 같은 JPA Auditing 관련 어노테이션들은 활성화되지 않아서 제대로 작동하지 않음

 

@EnableJpaAuditing은 스프링 애플리케이션에서 Auditing을 가능하게 하는 설정을 활성화하는 역할을 함

이러한 감사(Auditing) 어노테이션들은 엔티티가 생성되거나 변경될 때 자동으로 필드 값(생성 날짜, 변경 날짜, 생성자, 변경자 등)을 설정하는 기능을 제공함

 

@EnableJpaAuditing을 사용함으로써, JPA 엔티티의 생명주기에 대한 중요한 메타데이터를 자동으로 기록하여,

데이터의 추적, 감사 및 유지 보수 작업을 용이하게 함

 

다만, 이 기능을 사용하려면 엔티티 필드에 적절한 JPA 어노테이션을 추가하고, 필요한 경우 사용자 정의 AuditorAware 구현체를 제공해야 함


주요 기능

1. 자동 타임스탬프

생성일자(@CreatedDate), 수정일자(@LastModifiedDate) 필드에 자동으로 타임스탬프를 기록합니다.

 

2. 생성자 및 수정자 추적

생성자(@CreatedBy), 수정자(@LastModifiedBy) 필드에 자동으로 추적 정보를 기록

이 기능을 사용하기 위해서는 추가로 AuditorAware 인터페이스를 구현해야 함

이 인터페이스는 현재의 감사자(auditor, 보통 현재 로그인한 사용자)를 반환하는 메서드를 정의

 

사용 방법

1. 감사를 위한 기본 설정

메인 클래스 또는 설정 클래스에 @EnableJpaAuditing 애너테이션을 추가

 

2. 엔티티 클래스 필드에 감사 애너테이션 추가

필요한 필드에 @CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy 애너테이션을 적용

 

3. 감사자 인식 설정 (필요한 경우)

AuditorAware<T> 인터페이스를 구현한 빈을 등록

이를 통해 애플리케이션은 엔티티가 생성되거나 수정될 때, 누가 그 작업을 수행했는지 추적할 식별자를 자동으로 설정할 수 있음

 

 

예시

1. 보통 메인 어플리케이션 클래스나 별도의 설정 클래스에 @EnableJpaAuditing 어노테이션을 추가

메인 클래스에서 활성화하는 방법과 별도의 설정 클래스에서 활성화하는 두 가지 방법이 있음

 

메인 클래스에서 @EnableJpaAuditing 활성화

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@Configuration
@EnableJpaAuditing
public class MyApplicationConfig {
    // 기타 설정
}

 

별도의 설정 클래스에서 @EnableJpaAuditing 활성화

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfiguration {
}

 

 

2. 엔티티에 자동으로 날짜 및 시간 필드 설정

필요한 클래스의 필드에 직접 설정

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDateTime;

@Entity
@EntityListeners(AuditingEntityListener.class) // Auditing 기능 활성화
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    // Getters and setters
}

 

@EntityListeners(AuditingEntityListener.class)

목적
@EntityListeners 어노테이션은 엔티티에 하나 이상의 리스너 클래스를 등록하는 데 사용
AuditingEntityListener.class를 파라미터로 사용함으로써, 엔티티의 생명주기 이벤트(예: 생성, 수정)를 감지하고,
해당 이벤트가 발생할 때 자동으로 필드 값을 갱신하는 감사(Auditing) 기능을 활성화

사용 예시
BaseEntity 클래스에 @EntityListeners(AuditingEntityListener.class) 어노테이션을 사용함으로써,
@CreatedDate와 @LastModifiedDate 어노테이션이 적용된 필드의 값이
엔티티가 생성되거나 수정될 때 자동으로 현재 시간으로 설정되도록 함

@CreatedDate나 @LastModifiedDate의 값이 null로 나오면서 제대로 적용되지 않는다면
대부분 @EntityListeners(AuditingEntityListener.class) 어노테이션이 없어서 감사를 제대로 하지 못하기 때문이므로
해당 어노테이션을 추가해주면 문제가 해결됨

 

BaseEntity 클래스에 공통 속성 설정 후 상속하는 방법으로 사용

주로 CreatedDate 혹은 LastModifiedDate를 사용하는데,

해당 필드는 다른 엔티티에서도 공통으로 요구하는 속성이기 때문에

대체적으로 BaseEntity 클래스를 따로 생성하여 엔티티에 상속하는 방식을 사용함

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

    @CreatedDate
    private LocalDateTime createdDateTime;

    @LastModifiedDate
    private LocalDateTime modifiedDateTime;

}
@MappedSuperclass

목적
@MappedSuperclass 어노테이션은 공통 매핑 정보가 있는 엔티티 클래스의 슈퍼클래스에 사용
이 어노테이션이 붙은 클래스는 직접 생성되어 사용되는 엔티티가 아니며, 테이블과 직접적으로 매핑되지 않음
대신, 이 클래스를 상속받는 엔티티들이 슈퍼클래스의 매핑 정보(필드 및 애너테이션)를 상속받아 사용할 수 있게 됨

사용 예시
BaseEntity 클래스와 같이 여러 엔티티들에 공통으로 적용되어야 하는 필드(예: 생성 시간, 수정 시간)가 있을 때 사용
이러한 방식으로 코드 중복을 줄이고, 유지보수성을 향상시킬 수 있음

 

 

작동 원리

@EnableJpaAuditing 어노테이션이 작동하는 원리를 이해하려면, 스프링 프레임워크의 핵심 개념 몇 가지를 알아야 함

이 어노테이션은 스프링의 메타-애너테이션과 Import 애너테이션을 기반으로 동작하며, JPA 엔티티의 생명주기 이벤트를 가로채어 자동으로 필드 값(예: 생성 날짜, 수정 날짜)을 갱신함

핵심 개념

메타-어노테이션 (Meta-Annotation)

메타-어노테이션은 다른 애너테이션에 적용되는 어노테이션

@EnableJpaAuditing는 내부적으로 @Import 같은 메타-어노테이션을 사용

@Import 어노테이션

스프링의 @Configuration 클래스에서 사용되며, 주어진 구성 클래스를 애플리케이션 컨텍스트에 명시적으로 등록하기 위해 사용 @EnableJpaAuditing가 내부적으로 이를 사용하여 JPA 감사 관련 설정을 등록

AOP (Aspect-Oriented Programming)

관점 지향 프로그래밍은 특정 기능이나 관심사를 애플리케이션의 다른 부분과 모듈화하는 프로그래밍 패러다임

스프링 데이터 JPA는 엔티티의 생명주기 이벤트에 AOP를 적용하여 자동 필드 갱신이 이루어지도록 함

동작 원리

어노테이션 선언

@EnableJpaAuditing 어노테이션을 사용하면, JPA Auditing을 위한 설정을 스프링 컨텍스트에 등록하라는 선언

보통 이 어노테이션은 메인 애플리케이션 클래스나 별도의 설정 클래스에 추가

구성 클래스 등록

@EnableJpaAuditing 어노테이션 내부에서는 @Import(JpaAuditingRegistrar.class) (또는 비슷한 메커니즘)를 사용하여 JpaAuditingRegistrar 설정 클래스를 스프링 애플리케이션 컨텍스트에 등록

이 클래스는 JPA 감사를 활성화하는 데 필요한 구성 요소를 설정

감사 리스너 활성화

JpaAuditingRegistrar는 JPA 엔텔티의 생명주기 이벤트를 수신하기 위한 리스너를 등록

이 리스너는 @PrePersist, @PreUpdate 등의 JPA 이벤트에 반응하여,

지정된 필드(예: @CreatedDate, @LastModifiedDate)를 자동으로 업데이트함

Audit 기능 구현체 연결

리스너는 실제로 스프링 데이터의 AuditingEntityListener에 의해 구현됨

이 리스너는 엔티티의 생명주기 이벤트가 발생할 때마다, JPA 감사 필드를 채우는 로직을 실행

Audit 정보의 제공자 설정 (옵션)

사용자가 AuditorAware 인터페이스를 구현한 빈을 제공하면,

AuditingEntityListener는 이를 사용하여 @CreatedBy 및 @LastModifiedBy 필드에 값을 설정

이를 통해, 엔티티가 생성 또는 수정된 사용자를 추적할 수 있음

 

요약

@EnableJpaAuditing은 스프링 데이터 JPA의 Auditing 기능을 활성화하기 위한 설정을 등록

이 설정은 AOP와 JPA 생명주기 이벤트를 기반으로 하여, 애플리케이션 내의 엔티티 필드를 자동으로 갱신하는 메커니즘을 제공

이 모든 과정은 개발자가 직접 구현하지 않아도 되므로, 생산성과 정확성이 크게 향상됨