[개인 프로젝트(14)] JPA Auditing을 활용한 엔티티 메타데이터 구성 자동화

개발로그·2023년 12월 4일
0

개인 프로젝트

목록 보기
13/14
post-thumbnail


📌 메타데이터


💡 데이터를 위한 데이터
엔티티 메타 데이터 ⇒ 엔티티 생성일자, 생성자, 수정일자, 수정자





📌 JpaAuditingConfiguration


Spring Data JPA에서 제공하는 엔티티 감시(Auditing) 기능을 활성화하기 위해 @EnableJpaAuditing 어노테이션을 포함한 설정 클래스를 작성한다.

이를 통해, Spring Data JPA는 엔티티의 생명 주기 이벤트를 리스닝하며, 이벤트가 발생할 때 적절한 동작을 수행할 수 있도록 설정할 수 있다.

본 포스팅에서는 엔티티가 생성 또는 수정 될 때 메타데이터가 자동으로 설정되도록 하기 위해 @EnableJpaAuditing 어노테이션을 사용한다.


package com.ourhours.server.global.config.jpa;

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

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfiguration {
}




📌 BaseEntity


엔티티의 생명 주기 이벤트를 리스닝하며, 엔티티가 생성 또는 수정 될 때 메타데이터가 자동으로 설정되도록 하기 위한 클래스로, 다른 엔티티 클래스들이 상속 받아 사용할 수 있도록 한다.


package com.ourhours.server.global.model;

import java.time.LocalDateTime;

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

import com.ourhours.server.domain.member.domain.entity.Member;

import jakarta.persistence.EntityListeners;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;

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

	@CreatedDate
	private LocalDateTime createAt;

	@CreatedBy
	@ManyToOne
	private Member createdBy;

	@LastModifiedDate
	private LocalDateTime modifiedAt;

	@LastModifiedBy
	@ManyToOne
	private Member modifiedBy;

}


  • @MappedSuperclass
    : 해당 어노테이션이 포함된 클래스가 엔티티 클래스가 아니라, 매핑 정보를 포함한 부모 클래스임을 나타낸다.
    이 클래스를 상속하는 엔티티 클래스에서는 부모 클래스의 필드와 매핑 정보를 공유할 수 있기 때문에 공통적으로 사용되는 필드와 매핑 정보를 재사용 할 수 있게 된다.

  • @EntityListeners(AuditingEntityListener.class)
    : 해당 어노테이션이 포함된 클레스에 엔터티에서 발생하는 이벤트에 대한 리스너를 등록한다. 여기서는 AuditingEntityListener 를 사용하여 엔티티 생성일자, 생성자, 수정일자, 수정자와 같은 메타 데이터를 자동으로 관리할 수 있도록 한다.

  • @CreatedDate / @LastModifiedDate
    각각 엔티티의 생성일자와 마지막 수정일자를 나타낸다.

  • @CreatedBy / @LastModifiedBy
    각각 엔티티를 생성한 사용자와 마지막으로 수정한 사용자를 나타낸다.
    * 해당 어노테이션을 사용하기 위해서는 별도의 구현체가 필요하다.





📌 CustomAuditorAware


✅ AuditorAware

Spring Data JPA에서 제공하는 인터페이스 중 하나로, 엔터티의 생성자와 수정자를 자동으로 관리하기 위한 메서드 getCurrentAuditor를 정의하는 데 사용된다.

getCurrentAuditor 메서드는 현재 Audit 이벤트를 실행하는 사용자를 결정하기 위해 호출되는 메소드로, 일반적으로, 시스템에서 정의한 기준에 따라 생성자 또는 수정자를 결정하는 데 사용된다.

따라서, AuditorAware 인터페이스를 구현하면, getCurrentAuditor 메서드 내에서 필요한 로직을 구현하여 어떻게 현재 사용자를 식별할 지를 정의할 수 있다.


package com.ourhours.server.global.util.jpa;

import java.util.Optional;

import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import com.ourhours.server.domain.member.domain.entity.Member;
import com.ourhours.server.domain.member.repository.MemberRepository;
import com.ourhours.server.global.model.security.JwtAuthentication;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class CustomAuditorAware implements AuditorAware<Member> {
	private final MemberRepository memberRepository;

	@Override
	public Optional<Member> getCurrentAuditor() {
		return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
			.filter(Authentication::isAuthenticated)
			.map(authentication -> {
				JwtAuthentication jwtAuthentication = (JwtAuthentication)authentication;
				return memberRepository.findById(jwtAuthentication.getMemberId());
			})
			.orElse(Optional.empty());
	}

}

SecurityContextHolder.getContext().getAuthentication()이 null이 아니고
isAuthenticated 가 참인 경우에는, Authentication에 포함된 Member 식별자로 Member 객체를 찾아 반환하고,

그렇지 않은 경우에는, 빈 Optional 객체를 반환한다.




0개의 댓글