JAVA/JPA 학습기록

[JPA] Spring Data JPA로 생성일자, 수정일자 컬럼을 간단히 추가하자

kth990303 2022. 7. 29. 16:53
반응형

Spring Data JPA에는 Auditing 기능을 편하게 다룰 수 있도록 @CreatedDate, @LastModifiedDate 어노테이션을 제공해준다. 그리고 생성일자, 수정일자 컬럼은 웬만한 모든 도메인에 있으면 로깅 및 사용자 입장에서도 간편하다. 따라서 보통 BaseEntity라는 생성일자, 수정일자가 들어있는 상위 엔티티를 만들고 상속 구조를 이용하는 방법을 진행한다. 이번 포스팅에서는 이 방법에 대해 기록해보려 한다.


개발환경

  • Spring Boot 2 버전
  • Spring Data JPA
  • lombok

프로덕션 코드

BaseEntity

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

    @CreatedDate
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    @Column(name = "last_modified_at", nullable = false)
    private LocalDateTime lastModifiedDate;
}
  • 이벤트를 감지하여 생성일시와 수정일시를 체크해줄 수 있도록 Spring Data JPA에서 제공해주는@EntityListeners(AuditingEntityListener.class) 어노테이션을 추가했다.
  • 생성일자는 수정이 불가하도록 @Column(updatable = false) 어노테이션을 추가했다.
  • 각 엔티티는 위 BaseEntity를 상속받는다.
  • 해당 클래스는 인스턴스로 생성하지 못하도록 abstract로 막아두었다.

 

image

 

BaseEntity를 각 엔티티에서 상속받도록 한다면 위와 같은 형태가 될 것이고, 각 엔티티에는 extends 키워드를 사용하여 BaseEntity를 상속받도록 해주자. 그럼 자동으로 DB Table에 created_at, last_modified_at 컬럼이 추가되며, default값으로는 LocalDateTime.now()가 들어가게 된다.

 

웹 애플리케이션 실행 시 DB 테이블 컬럼에 생성일자, 수정일자가 자동으로 추가됨.


또한, SpringBootApplication에 @EnableJpaAuditing 어노테이션을 추가해주어 Jpa Auditing 기능을 사용할 수 있도록 해주어야 한다. 메인 클래스에선 Config 어노테이션을 지양하는 편이 좋기 때문에 config 패키지에 클래스를 하나 만들어서 아래와 같이 작업해주자.

JpaAuditingConfig

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfig {
}

@Configuration 어노테이션을 걸어주어 스프링 빈으로 관리하게 해놓았다.


테스트 코드

Jpa Auditing을 테스트하기 위해선 DB에 저장되고 수정이 일어났을 때를 바탕으로 진행돼야 하기 때문에 Repository 테스트로 진행하였다.

생성일자 테스트

@Test
@DisplayName("회원을 생성할 때 생성일자가 올바르게 나온다.")
void createMemberWhen() {
    final Member member = new Member("alex", "alex@naepyeon.com", "abc12345");
    final Long memberId = memberRepository.save(member);

    final Member actual = memberRepository.findById(memberId)
            .orElseThrow();
    assertThat(actual.getCreatedDate()).isAfter(LocalDateTime.MIN);
}

회원이 DB에 저장될 때의 시각이 생성일자이므로, 위와 같이 DB에 회원을 저장하고 JUnit 문법의 isAfter로 생성일자가 잘 생성됐는지 테스트했다.

수정일자 테스트

@Test
@DisplayName("회원 정보를 수정할 때 수정일자가 올바르게 나온다.")
void updateMemberWhen() {
    final Member member = new Member("alex", "alex@naepyeon.com", "abc12345");
    final Long memberId = memberRepository.save(member);
    em.flush();

    member.changeUsername("kth990303");
    em.flush();

    final Member actual = memberRepository.findById(memberId)
            .orElseThrow();
    assertThat(actual.getLastModifiedDate()).isAfter(actual.getCreatedDate());
}

회원을 저장한 후에, 이름을 수정하고 Flush하여 업데이트가 반영되도록 하였다. Repository Test는 @SpringBootTest 어노테이션이 붙어져있었기 때문에 @Autowired로 EntityManager를 호출할 수 있었다. 수정일시가 생성일시보다 이후일 경우에 테스트가 통과되도록 설정했다.


위와 같이 Spring Data JPA에서의 Auditing 기능을 이용해 각 도메인의 변경을 최소화하여 생성일자와 수정일자 컬럼을 추가할 수 있었다.

반응형