@PrePersist 와 @PreUpdate
Entity가 DB에 Persist(삽입) 되거나 Update(수정) 될 때
자동으로 호출되는 메서드를 정의하는 데 쓰이는 어노테이션이다.
기존에 어떻게 사용하고 있었냐면 created_at 같은 데이터를 기록 할 때
@Column
private LocalDateTime createdAt;
와 같이 콜백을 위해@EntityListener를 만들어 저장과 업데이트를 해 왔었다.
@PrePersist가 적용된 메서드는
내가 Entity를 만들고 save를 하고 싶을 때,
Entity가 영속성 컨텍스트에 저장되기 전에 @PrePersist가 달린 메서드가 호출이 된다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
@PrePersist
public void prePersist() {
// 엔티티가 새로 추가되기 전에 실행되는 로직
System.out.println("Before persisting the entity");
}
// Getter, Setter, 기타 메서드...
}
다음과 같은 예시로 사용이 된다.(PreUpdate도 동일)
그럼 createdAt과는 어떤 관계가 있는걸까?
일반적으로 createdAt도 일반적으로 날짜와 시간을 추적하기 위한 엔티티 필드다.
persist와 update는 메서드 수준의 어노테이션이다.
바로 위 예시에서 볼 수 있듯 createdAt과 같은 필드의 초기값을 설정하거나 수정할 때 사용하면 된다!
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
@PrePersist
public void prePersist() {
this.createdAt = LocalDateTime.now(); // 엔티티 생성 시 생성 시간 설정
this.updatedAt = this.createdAt; // 생성 시 업데이트 시간도 동일하게 설정
}
@PreUpdate
public void preUpdate() {
this.updatedAt = LocalDateTime.now(); // 엔티티 업데이트 시 업데이트 시간만 갱신
}
}
결론
결론적으로 이 어노테이션(@PreUpdate)은
soft delete를 하기 위해 검색하다가 알게 되었으며,
사용법은 Entity 내부에
# entity
@PreUpdate
public void updateDeleteField(){
if(status == Status.DELETED) {
this.deletedAt = LocalDateTime.now();
this.deletedBy = id;
}
}
와 같은 메서드를 선언한 후,
# service
@Transactional
public ResponseEntity<String> deleteStore(Long id) {
Store store = storeRepository.findById(id).orElseThrow(IllegalArgumentException::new);
store.delete(id);
return ResponseEntity.status(HttpStatus.OK).body("삭제 완료");
}
# entity
public void delete(Long id) {
this.status = Status.DELETED;
}
위와 같이 service에서 update(delete) 메서드를 사용하면 자동으로 사용된다!