[Spring Data] Spring Data JPA - Entity Listener

p1atin0uss·2022년 6월 25일
0

JPA

목록 보기
3/3

📌 Entity Listener

개념

Entity의 변화를 감지하고, 지정된 동작이 실행되면 해당 엔티티의 데이터를 조작해주는 기능을 의미한다.

> 특정 Entity의 CRUD 이벤트(INSERT, UPDATE, DELETE, SELECT)가 발생 했을 경우,
  해당 애너테이션(@PrePersist, @PostPersist 등)에 지정된 Method를 실행시킨다.

Entity Listener Annotation

특정 시점에 해야 할 행동들을 정의하는 애너테이션이다.

> Method 실행 전

@PrePersist : INSERT 메서드가 호출되기 직전
@PreUpdate : UPDATE 메서드가 호출되기 직전
@PreRemove : DELETE 메서드가 호출되기 직전

> Method 실행 후

@PostPersist : INSERT 메서드가 호출된 직후
@PostUpdate : UPDATE 메서드가 호출된 직후
@PostRemove : DELETE 메서드가 호출된 직후
@PostLoad : SELECT 메서드가 호출된 직후


적용사례

User라는 Entity에 INSERT 혹은 UPDATE가 일어났을 시에, 생성일자와 수정일자를 추가 및 수정하는 기능을 구현하고자 한다.

> 유저가 회원 가입을 했을 시에, 생성일자 및 수정일자도 user정보와 함께 저장한다 등 

생성일자와, 수정일자에 대한 필드 및 컬럼은 이미 Spring Data JPA에서 Auditing Entity Listener로 구현할 수 있게 제공하고 있다. 이를 인지하고 구현해보자.

먼저 모든 Entity들은 생성일자와, 수정일자를 포함하고 있을 것이므로, 중복 코드를 방지하기 위해 인터페이스와 엔티티를 따로 뽑아보고자 한다.


/**
 * Auditable.java
 */
 
 public interface Auditable {
 	LocalDateTime getCreatedAt();
    LocalDateTime getUpdatedAt();
    
    void setCreatedAt(LocalDateTime createdAt);
    void setUpdatedAt(LocalDateTime updatedAt);
 }
/**
 * BaseEntity.java
 */
 
 @Data
 @MappedSuperclass
 @EntityListeners(value = AuditingEntityListener.class)
 public class BaseEntity implements Auditable {
 	@CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;
 }

@MappedSuperclass는 해당 클래스의 필드를 상속받는 엔티티의 column으로 추가하도록 지정하는 애너테이션이다.

또한 @EntityListeners는 해당 Event를 listen해주는 클래스를 선언하는 애너테이션을 뜻하며, @CreatedDate@LastModifiedDate는 각각 생성일자 및 변경일자를 선언된 필드(또는 컬럼)에 저장되도록 지정해주는 애너테이션이다.

> AuditingEntityListener는 Spring에서 제공하는 Entity Listener 클래스이다.

마지막으로 @CreatedDate@LastModifiedDate를 사용하기 위해 JPA Auditing 기능을 활성화 시켜야 하는데 @EnableJpaAuditing을 이용하여 활성화 시켜준다.

/**
 * JpaConfiguration.java
 */


@Configuration
@EnableJpaAuditing
public class JpaConfiguration { }

이렇게 선언한 EntityListener를 User 엔티티에 적용해보자


/**
 * User.java
 */
 
@Entity
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class userInfo extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    ...
    
}

위에서 구현한 BaseEntity를 상속 받는 방식으로 작성하게 되면, 다음과 같은 이점이 있게된다.

  • Entity마다 반복적으로 생성일자 및 수정일자 필드를 선언하지 않아도 된다.
  • @PrePersist 및 @PreUpdate를 반복적으로 선언하지 않아도 된다.
  • EntityListener를 추가적으로 지정해주지 않아도 해당 event가 발생할 때마다 생성일자와 수정일자가 자동으로 저장되게 된다.

Spring Data JPA에서는 생성일자 및 수정일자에 대한 EntityListener를 제공해주어서 @CreatedDate@LastModifiedDate를 사용하였지만, 직접 custom해서 사용해야 할 경우에는 BaseEntity 클래스를 Entity Listener Annotation을 이용하여 구현해주면 된다.

profile
지식의 깊이는 곧 이해의 넓이 📚

0개의 댓글