중복되는 createdAt, updatedAt 필드 관리하기
팀프로젝트 중 도메인별로 개발하다보니
각자의 Entity에 createdAt, updatedAt 필드가 중복되었고 통일되지도 않았다.
중복을 없애고 통일시킬 필요가 있다고 느꼈다.
기존 상황
/* 내 코드 */
public class Review {
// ... 중략 ...
@Column(updatable = false)
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
@PrePersist
protected void prePersist() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
}
나는 @PrePersist와 @PreUpdate 어노테이션을 사용하여
데이터 생성 시점과(createdAt), 데이터 업데이트 시점(updaetdAt)을 관리하였다.
/* 팀원 코드 */
public class Users {
// ... 중략 ...
@Column(name = "created_at")
@CreatedDate
private Date createdAt;
@Column(name = "modified_at")
@LastModifiedDate
private Date modifiedAt;
}
팀원은 @CreatedDate와 @LastModifiedDate 어노테이션을 사용하여
데이터 생성 시점과(createdAt), 데이터 업데이트 시점(modifiedAt)을 관리하였다.
개선 상황
1. 중복되는 필드를 엔티티로 따로 분리
- 엔티티로 따로 분리함으로써 중복을 피하고 재사용이 가능
- 해당 엔티티에는 시간과 관련된 로직만(단일 책임) 있기 때문에 변경과 확장이 편하고 코드가 간결
2. 객체의 생성 및 수정 시간을 추적하기 위한 방법으로 @CreatedDate와 @LastModifiedDate 어노테이션을 사용
- 엔티티의 저장 및 수정 시간을 자동으로 업데이트
- 코드량이 적고 일관된 방식으로 시간을 추적할 수 있어 편리
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@Entity
@Getter
@RequiredArgsConstructor
public class Review extends BaseTimeEntity {
// ... 중략 ...
}
@MappedSuperClass
- 부모 클래스는 테이블과 매핑하지 않고, 자식 클래스에게 부모 클래스가 가지는 컬럼 정보를 제공하는 역할
- 다른 엔티티들이 BaseTimeEntity를 상속할 경우, BaseTimeEntity의 필드를 컬럼으로 인식
@EntityListeners
- 엔티티 클래스에 붙여서 해당 엔티티의 생명주기 이벤트를 감시하고 처리할 리스너 클래스를 지정
- 엔티티에 특정 로직을 적용하거나 이벤트를 감시하는 데 유용
- ex) 엔티티가 저장되기 전에 특정 로직을 실행하거나, 수정되었을 때 로그를 기록하는 등의 작업을 수행