[JPA] 데이터에 생성시간과 수정시간 포함시키기

Kaite.Kang·2022년 12월 30일
0
post-thumbnail

* 목표

JPA Auditing으로 생성시간/수정시간 자동화하기

1. JPA Auditing

1) 개념

엔티티(Entity)에는 해당 데이터의 생성시간과 수정시간을 포함해야 한다.
언제 만들어졌는지, 언제 수정되었는지 등은 차후 유지보수에 있어 중요한 정보이기 때문이다.
그렇다 보니 매번 DB에 삽입하기 전, 생성하기 전에 날짜 데이터를 등록/수정하는 코드가 들어가게 된다.

//생성일 추가 코드 예제
public void savePosts(){
...
posts.setCreateDate(new LocalDate());
postsRepository.save(posts);
...
}

이렇게 반복적으로 코드가 모든 테이블과 서비스 매소드에 포함되어야 한다면 번거롭고, 지저분한 코드가 된다.
이 문제는 JPA Auditing을 사용하여 해결 할 수 있다.

JPA에서는 Audit이라는 기능을 제공하고 있다. Audit은 감시하다, 감사하다라는 뜻으로 Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능이다.

2. 날짜와 시간 데이터 타입

  • LocalDate, LocalDateTime
    • JAVA에서는 시간와 시간을 저장할 데이터 타입으로 LocalDate, LocalDateTime 을 제공한다.
    • Java8부터 적용 가능한 날짜 데이터 타입이다.
    • Date 타입도 있지만 여러 버그로 인해 사용을 권장하지 않는다.

3. 코드 작성하기

1) BaseTimeEntity 작성

이 클래스는 모든 엔티티의 상위 클리스가 되어 엔티티들의 createDate, modefiedDate를 자동으로 관리하는 역할을 한다.

package com.spring.book.domain;

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

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass //(1)
@EntityListeners(AuditingEntityListener.class) //(2)
public class BaseTimeEntity {
    
	@CreatedDate //(3)
    private LocalDateTime createdDate;

    @LastModifiedDate //(4)
    private LocalDateTime modifiedDate;
}
  • (1) @MappedSuperclass
    JPA 엔티티 클래스들이 BaseTimeEntity를 상속할 경우 필드들(createdDate, modifiedDate)도 칼럼으로 인식하도록 한다.

  • (2) @EntityListeners(AuditingEntityListener.class)
    BaseTimeEntity 클래스에 Auditing 기능을 포함시킨다.

  • (3) @CreatedDate
    엔티티가 생성되어 저장될 때 시간이 자동으로 저장된다.

  • (4) @LastModifiedDate
    조회한 엔티티의 값을 변경할 때 시간이 자동 저장된다.

2) Post 클래스가 BaseTimeEntity를 상속받도록 변경

...
public class Posts extends BaseTimeEntity {
...
}

3) @EnableJpaAuditing 어노테이션 추가

마지막으로 Application 클래스에 활성화 어노테이션(@EnableJpaAuditing)을 추가하면 JPA Auditing 어노테이션들을 모두 활성화된다.

@EnableJpaAuditing
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

4. 테스트 코드 작성하기

  • 테스트 코드
@Test
    public void BaseTimeEntity_등록(){
        //given
        LocalDateTime now = LocalDateTime.of(2022,10,16,3,33,0);
        postsRepository.save(Posts.builder()
                .title("title")
                .content("content")
                .author("author")
                .build());

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

        //then
        Posts posts = postsList.get(0);
        System.out.println(">>>>>>>>> createDate=" + posts.getCreatedDate() + ", modifiedDate=" + posts.getModifiedDate());
        assertThat(posts.getCreatedDate().isAfter(now));
        assertThat(posts.getModifiedDate().isAfter(now));
    }
  • 테스트 코드 실행 결과
...
2022-10-16 15:39:49.326  INFO 1637 --- [           main] c.s.b.domain.posts.PostRepositoryTest    : Started PostRepositoryTest in 1.517 seconds (JVM running for 1.884)
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
>>>>>>>>> createDate=2022-10-16T15:39:49.407562, modifiedDate=2022-10-16T15:39:49.407562
...

테스트 코드를 수행해 보면 시간이 잘 저장되는 것을 확인할 수 있다.

* 정리

  • 엔티티들은 BaseTimeEntity만 상속받으면 등록일/수정일 데이터를 자동으로 해결할 수 있다.

참고

도서 - 스프링 부트와 AWS로 혼자 구현하는 웹 서비스

0개의 댓글