[JPA] @CreatedDate, @CreatedBy, @LastModifiedDate, @LastModifiedBy, auditorAware, @EnableJpaAuditing 통해서 생성일시, 변경일시 관리하기
1. Intro
데이터를 관리할 때 처음 저장된 일시, 유저, 마지막으로 저장된 일시, 유저 데이터를 관리하는 것은 중요하다. 오늘은 JPA에서 annotation을 사용해서 이들을 관리하는 방법을 알아보도록 하겠다.2. Annotation
1) @CreatedDate
데이터가 "생성된 시간 정보"를 관리하는 annotation이다. 참고로 main method가 실행되는 class에 @EnableJpaAuditing annotation을 적용하여야 이 일시에 null이 아닌, 실제 생성된 시간 정보가 들어간다.
3. @CreatedBy
처음 데이터를 생성한 user 정보를 넣어준다. @CreatedDate와는 달리 따로 Spring에서 알 수 있는 방법이 없기 때문에 따로 auditorAware를 사용하여 구현해줄 수 있다.
package com.example.projectboard.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import java.util.Optional;
@EnableJpaAuditing
@Configuration
public class JpaConfig {
@Bean
public AuditorAware<String> auditorAware(){
return () -> Optional.of("user1");
}
}
3) @LastModifiedDate
2번 @CreatedDate와 비슷하게 일시를 나타내주는 데이터인데, @LastModifiedDate를 통해 가장 마지막으로 변경된 일시를 나타내준다.
change된 데이터의 이력을 관리하는 목적으로 사용된다.
4) @LastModifiedBy
3번 @CreatedBy와 유사하게 데이터를 변경한 사용자를 관리하는 목적으로 사용된다. @CreatedBy가 가장 처음에 데이터를 생성한 유저를 나타낸다면 @LastModifiedBy는 가장 마지막으로 데이터를 변경한 유저를 나타낸다.
3. 예시코드 - 생성일시, 변경일시 등을 관리하는 게시글 Entity 만들기
위 네 개의 데이터를 관리할 수 있는 것이 대표적으로 게시글이라고 할 수 있다. Article이라는 이름으로 Entity를 만들면 아래와 같이 만들 수 있다. 전체 코드를 아래와 같이 살펴보자.
package com.example.projectboard.domain;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
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 java.time.LocalDateTime;
import java.util.Objects;
@Getter
@ToString
@Table(indexes = {
@Index(columnList = "title"),
@Index(columnList = "createdAt"),
@Index(columnList = "createdBy")
})
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Setter
private String title;
@Setter @Column(nullable = false) private String content;
@CreatedDate @Column(nullable = false) private LocalDateTime createdAt;
@CreatedBy @Column(nullable = false, length = 200) private String createdBy;
@LastModifiedDate @Column(nullable = false) private LocalDateTime modifiedAt;
@LastModifiedBy @Column(nullable = false, length = 200) private String modifiedBy;
protected Article(){
}
private Article(String title, String content) {
this.title = title;
this.content = content;
}
private Article of(String title, String content) {
return new Article(title, content);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Article article)) return false;
return id != null && id.equals(article.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
참고로 id는 @GeneratedValue를 사용하여 생성되도록 하였다.
나머지는 @Column annotation을 사용하여 nullable 여부와 length를 표시해주었다.