[Spring] @PrePersist, @PreUpdate

김한준 Hanjun Kim·2024년 11월 11일

Spring

목록 보기
1/6

@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) 메서드를 사용하면 자동으로 사용된다!

profile
개발이 하고싶은 개발지망생

0개의 댓글