카테고리 없음

[JPA] EntityListener사용하기

o_b:us 2022. 1. 8. 17:48

엔티티 리스너 콜백 옵션

@PrePersist

  • before persist is called for a new entity
    //insert 쿼리 이전에 대응

@PreUpdate

  • before the update operation
    //update 쿼리 이전에 대응

@PreRemove

  • before an entity is removed
    //delete 쿼리 이전에 대응

@PostPersist

  • after persist is called for a new entity
    //insert 쿼리 이후에 대응

@PostUpdate

  • after and entity is updated
    //update 쿼리 이후에 대응

@PostRemove

  • after and entity has been deleted
    //delete 쿼리 이후에 대응

@PostLoad

  • after and entity has been loaded
    //select 쿼리 이후에 대응

엔티티 리스너에는 위와 같은 콜백 옵션들이 있다.

엔티티 내부에서 직접 메서드를 만들어 주는 방법

엔티티 리스너를 따로 만들어 주는 방법이 있다.



엔티티 내부에서 메서드로 사용하는 방법

예를들어 아이디,이름, 생성시간, 업데이트 시간으로 이루어진

User라는 엔티티가 있다면 아래와 같이 엔티티내에 메서드를 작성해서 사용할 수 있다.

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NonNull
    private String name;

    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;

//엔티티 리스너 메서드
    @PrePersist
    public void prePersist() {
        this.createdAt = LocalDateTime.now();
        this.updatedAt = LocalDateTime.now();
    }

    @PreUpdate
    public void preUpdate() {
        this.updatedAt = LocalDateTime.now();
    }
}

물론 jpa에서 제공해주는 @CreatedDate와, @LastModifiedDate 이러한 기본 리스너들을 이용하여 아래와 같이 작성해줘도 된다.

@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;

@LastModifiedDate
private LocalDateTime updatedAt;



엔티티 리스너를 따로 만들어 주는 방법

생성시간과 업데이트시간은 사실 User라는 엔티티 뿐만 아니라 다른 엔티티에서도 필요로 하는 속성이다. 매번 위와 같은 메서드를 작성한다 생각하면 정말 불편하다. 아래와 같이 Auditable 인터페이스를 만들어주고 MyEntityListener 클래스를 만들어주고
Entity에 @EntityListeners(value = MyEntityListenr.class)를 설정해준다.

public interface Auditable {
    LocalDateTime getCreatedAt();
    LocalDateTime getUpdatedAt();

    void setCreatedAt(LocalDateTime createdAt);
    void setUpdatedAt(LocalDateTime updatedAt);
}

public class MyEntityListener {
    @PrePersist
    public void prePersist(Object o) {
        if(o instanceof Auditable){
            ((Auditable) o).setCreatedAt(LocalDateTime.now());
            ((Auditable) o).setUpdatedAt(LocalDateTime.now());
        }
    }

    @PreUpdate
    public void preUpdate(Object o){
        if(o instanceof Auditable){
            ((Auditable) o).setCreatedAt(LocalDateTime.now());
            ((Auditable) o).setUpdatedAt(LocalDateTime.now());
        }
    }
}

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Entity
//엔티티리스너 설정
@EntityListeners(value = MyEntityListener.class)
public class User implements Auditable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NonNull
    private String name;

    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;

}