JPA Auditing

my_mon·2023년 3월 19일
0
post-thumbnail
post-custom-banner

JPA Auditing이란?

생성일, 수정일 같은 중요한 정보를 기록하는 코드가 모든 테이블과 서비스 메소드에 반복적으로 작성된다면, 귀찮고 자칫 코드가 지저분해질 수 있다.
이런 문제를 해결하고자 JPA Auditing을 사용해 보려고 한다.

JPA Auditing은 JPA를 사용하여 엔티티의 생성일, 수정일 같은 정보를 자동으로 기록하고 추적하는 기능인데, 일반적으로 Spring Data JPA와 함께 사용된다.

JPA Auditing을 구련하려면 엔티티에 @EntityListeners 어노테이션을 사용하여 리스너를 등록해야 한다. 이 리스너는 엔티티의 상태가 변경될 때 마다 콜백 메소드를 호출하여 적절한 정보를 추적하고 기록한다.

JPA Auditing 적용

JPA Auditing 기능을 사용하기 위해 다음과 BaseTime엔티티를 생성한다.

@Getter
@EnableJpaAuditing
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime modifiedDate;
}

잠시 위의 코드를 설명해보자면

@EnableJpaAuditing
JPA Auditing 어노테이션들을 모두 활성화 시키는 어노테이션

@MappedSuperClass
JPA 어노테이션. 엔티티에서 공통적으로 사용하는 필드를 정의하는 추상 클래스임을 나타낸다. 즉, JPA Entity 클래스들이 BaseTimeEntity를 상속할 경우 필드들(createdDate, modifiedDate)도 컬럼으로 인식하도록 한다.

@EntityListeners(AuditingEntityListener.class)
JPA Auditing을 구현하기 위한 어노테이션 중 하나로, BaseEntity 클래스에서 리스너를 사용하도록 설정한다.

@CreatedDate
Entity가 생성되어 저장될 때 시간이 자동으로 저장된다.

@LastModifiedDate
조회된 Entity의 값을 변경할 때 시간이 자동으로 저장된다.


JPA Auditing 테스트 코드 작성

위와 같이 실제 구현 코드를 완성시켰으니, 이제 제대로 작동하는지 테스트를 해보자.

package com.myshop.domain.posts;

import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.time.LocalDateTime;
import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest // 별다른 설정 없이 이 어노테이션을 사용할 경우 H2 데이터베이스를 자동으로 실행해줌
public class PostsRepositoryTest {

    @Autowired
    PostsRepository postsRepository;

    @After
    public void cleanup() {
        postsRepository.deleteAll();
    }

    @Test
    public void BaseTimeEntityTest() {

        //given
        LocalDateTime now = LocalDateTime.of(2023,3,19,0,0,0);
        postsRepository.save(Posts.builder()
                .title("생성일 제목")
                .content("생성일 내용")
                .author("테스트~")
                .build()
        );

        //when
        List<Posts> postsLists = postsRepository.findAll();

        //then
        Posts posts = postsLists.get(0);

        System.out.println(">>>> createdDate=" + posts.getCreatedDate()+", modifiedDate=" + posts.getModifiedDate());

        assertThat(posts.getCreatedDate()).isAfter(now);
        assertThat(posts.getModifiedDate()).isAfter(now);
    }

}

위 테스트 코드에서는 현재 시점의 LocalDateTime 정보를 생성한다.
생성된 정보는 save 메소드로 객체를 저장할 때 BaseEntity 클래스의 생성일(createdDate)과 수정일(modifiedDate) 정보가 자동으로 기록된다.

그 후, findAll() 메소드로 저장된 리스트들을 모두 불러온 뒤, 첫번째 엔티티 객체를 선택하여 posts 변수에 저장한 후 결과를 출력한다.

마지막으로 Posts 엔티티 객체의 생성일과 수정일이 테스트시점의 LocalDateTime 정보(now) 이후임을 검증한다.

테스트코드를 실행해보면 콘솔창에 createdDate와 modifiedDate가 조회된다!

참고 : 스프링 부트와 AWS로 혼자 구현하는 웹 서비스

profile
기록하는 사람
post-custom-banner

0개의 댓글