Skip to content

[기능추가] Entity에 생성일자, 수정일자 필드 추가하기

TaeHyeon Kim edited this page Jul 26, 2022 · 1 revision

Spring Data JPA에는 Auditing 기능을 편하게 다룰 수 있도록 @CreatedDate, @LastModifiedDate 어노테이션을 제공해줍니다. 작업을 하면서 각 도메인에 생성일자, 수정일자 필드가 추가되면 편리하겠다는 생각이 들어 이번 스프린트3 때 해당 필드를 추가하게 됐습니다. 해당 필드는 모든 도메인에서 필요로 했기 때문에 BaseEntity라는 상위 엔티티를 만들어 해당 필드를 생성해주었고, @MappedSuperClass 어노테이션을 이용해 JPA에서 지원하는 상속 기능을 사용하였습니다. 프로덕션 코드를 보면서 어떻게 기능을 추가했는지 직접 알아보고, 테스트 코드를 보면서 어떻게 테스트하였는지 알아보는 시간을 가져봅시다.

프로덕션 코드

BaseEntity

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

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
}
  • 이벤트를 감지하여 생성일시와 수정일시를 체크해줄 수 있도록 Spring Data JPA에서 제공해주는 @EntityListeners(AuditingEntityListener.class) 어노테이션을 추가했습니다.
  • 생성일자는 수정이 불가하도록 @Column(updatable = false) 어노테이션을 추가하였습니다.
  • 각 엔티티는 위 BaseEntity를 상속받습니다.
image

위 기능을 사용하기 위해서는 main 메서드가 포함된 Application에 @EnableJpaAuditing 어노테이션을 추가해주어야 합니다. NaepyeonApplication

@EnableJpaAuditing
@SpringBootApplication
public class NaepyeonApplication {

    public static void main(String[] args) {
        SpringApplication.run(NaepyeonApplication.class, args);
    }
}

테스트 코드

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

생성일자 테스트

@Test
@DisplayName("회원을 생성할 때 생성일자가 올바르게 나온다.")
void createMemberWhen() {
    final Member member = new Member("alex", "[email protected]", "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", "[email protected]", "abc12345");
    final Long memberId = memberRepository.save(member);

    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 기능을 이용해 각 도메인의 변경을 최소화하여 생성일자와 수정일자 컬럼을 추가할 수 있었습니다.