[JPA] EntityListeners 정리
# 서론
게시글이나 댓글 CRUD를 구성할때, 생성일과 수정일을 포함하고 싶은 경우가 있다.
이럴때 그냥 LocalDateTime을 엔티티 멤버변수로 넣어놔도 되지만 이러면 디비에 들어가는 양식이 이쁘지가 않다. (즉 포맷을 커스터마이징 하고 싶다.)
이를 편리하게 해주는게 하이버네이트에서 제공하는 EntityListener라는 기능을 알아보자
# EntityListener란?
하이버네이트가 DB에 어떤 행위를 하는 시점이나 그 이후 등 호출될 수 있는 콜백함수를 제공해주는 어노테이션이다.
즉, DB에 엔티티를 저장하기 전에 특정 행위를 할 수 있게 해준다. (MVC의 인터셉터와 비슷하다고 보면 된다.)
제공되는 콜백 옵션은 다음과 같다.
@PrePersist
manager persist 의해 처음 호출될 때 실행
@PostPersist
manager persist 에 의해 실행되고 호출 (SQL INSERT 이후에 대응)
@PostLoad
로드 이후에 호출 (SQL SELECT 이후에 대응)
@PreUpdate
SQL UPDATE 이전에 호출
@PostUpdate
SQL UPDATE 이후에 호출
@PreRemove
SQL DELETE 이전에 호출
@PostRemove
SQL DELETE 이후에 호출
# 사용 예제
우리는 엔티티 클래스의 부모클래스로 작동할 BaseTimeEntity를 만들고 여기서는 작성일과 수정일을 공용으로 관리할 것이다. 게시글과 댓글 처럼 생성일, 수정일이 필요한 엔티티에 이 BaseTimeEntity를 상속받아서 구현하도록 할 것이다.
이렇게 하면 다음과 같은 이점이 있다.
- 생성일과 수정일이 필요한 엔티티 클래스에 공용되고 재사용성 높게 해당 멤버 변수를 부여할 수 있다.
- 시간 표시를 포멧팅하기 쉬워진다.
@Getter
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class BaseTimeEntity {
@CreatedDate
private String createdDate;
@LastModifiedDate
private String updatedDate;
@PrePersist
public void onPrePersist(){
this.createdDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
this.updatedDate = this.createdDate;
}
@PreUpdate
public void onPreUpdate(){
this.updatedDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
}
}
@MappedSuperclass : 엔티티 클래스가 이 클래스를 상속 받아서 사용한다고 표시해주는 어노테이션. 이걸 붙혀야 해당 필드의 멤버 변수를 매핑받아 DB 칼럼으로 잘 들어간다.
@EntityListeners(AuditingEntityListener.class) : JPA에서 제공하는 Auditing 기능을 사용하겠다는 뜻.
@PrePersist나 @PreUpdate를 보면 데이터 포맷을 커스터마이징 했다.
이제 사용이 필요한 엔티티에 BaseTimeEntity를 상속받고, 생성일이나 수정일 정보가 필요하면 getCreatedDate(), getUpdatedDate() 메소드로 접근하면 된다. (Getter를 열어 놔서 가능하다.)