디자인너 코딩하기

Entity Listener - ① 본문

spring/Entity

Entity Listener - ①

designercoding 2022. 4. 19. 09:13

Listener

특정 이벤트를 관찰하면서, 관찰했던 이벤트가 발생하면 맞는 이벤트 실행 


방법

1. Entity 내에서 어노테이션으로 자체적으로 Listener 구현

어노테이션 관찰이벤트 비고
@PrePersist insert가 실행 전에 create(많이 사용됨)-감시목적
@PreUpdate merge가 실행 전에 update(많이 사용됨)-감시목적
@PreRemove delete가 호출 되기 전 delete
@PostPersist insert가 실행 후 create
@PostUpdate merge가 호출 후 update
@PostRemove delete가 호출 후 delete
@PostLoad select가 호출 된 직후 read

- 사용방법

private LocalDateTime createdAt;
private LocalDateTime updatedAt;

@PrePersist
public void prePersist(){
  this.createdAt = LocalDateTime.now();
}

@PreUpdate
public void preUpdate(){
  this.updatedAt = LocalDateTime.now();
}
@PrePersist
public void prePersist(){
  이벤트...
}

공통으로 사용되는 이벤트가 아니라면 각 Entity에 실행 메서드를 만들어 어노테이션을 넣는다.

 

방법

1. Entity 내에서 어노테이션으로 자체적으로 Listener 구현 심화

방법 1에 확장으로 공통으로 사용되는 이벤트라면 Entity Listener를 만들어 공통으로 사용한다

 

EntityListener class를 생성 후 사용할 해당 Entity에 @EntityListeners 넣어준다.

@EntityListners(value = 해당 Listener.class)

@EntityListners(value = {해당 1 Listener.class, 해당 2 Listener.class})

 

workFlow

1.

Auditable 인터페이스로 데이터 전달 목적의 클래스를 정의하고

2.

Auditable 매개체로 하는 Listener를 만들고

3.

해당 Entity에서 @EntityListners를 이용해 해당 Listener 기능을 장착한다.

 

Auditable.java

import java.time.LocalDateTime;

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

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

- 공통으로 Listener에 사용할 필드 된 인터페이스 객체로 만들어 전달 목적(인식)으로 사용

 

MyEntityListener.java

import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import java.time.LocalDateTime;

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

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

- object로 받아야 한다.

entity 내에 사용하는 Listener는 this 받을 수 있다. 하지만 클래스로 Listener로 만든다면 어떤 타입을 받아야 하는지 알기 힘들기 때문에 object로 받는다

- 위에 만든 Auditable 인터페이스 형이 맞는지 확인 후 Listener 실행

 

User.java

@Data
@EntityListeners(value= MyEntityListener.class)
public class User implements Auditable {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  private String email;
  private LocalDateTime createdAt;
  private LocalDateTime updatedAt;
}

- Auditable 인터페이스 구현함으로써 객체를 매개체로 이용하여 EntityListeners를 사용한다.

- implements Auditable를 하지 않으면 createdAt과 updatedAt의 값이 null로 리턴된다.


User Entity를 입력하면 자동으로 UserHistory도 입력

Entity Listener는 Spring Bean를 주입받지 못한다.

→ @Component 사용 시 null pointException 발생

 

Bean를 주입받는 static method를 만들어 주입한다.

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class BeanUtils implements ApplicationContextAware {

  private static ApplicationContext applicationContext;

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    BeanUtils.applicationContext = applicationContext;
  }

  public static <T> T getBean(Class<T> clazz){
    return applicationContext.getBean(clazz);
  }

}
public class UserEntityListener {

  @PrePersist
  @PreUpdate
  public void prePersistAndPreUpdate(Object o){
    UserHistoryRepository userHistoryRepository = BeanUtils.getBean(UserHistoryRepository.class);

    User user = (User) o;
    UserHistory userHistory = new UserHistory();
    userHistory.setUserId(user.getId());
    userHistory.setName(user.getName());
    userHistory.setEmail(user.getEmail());

    userHistoryRepository.save(userHistory);
  }
}

 

방법

2. Spring의 기본 Entity Listener 사용

다음 장에서 소개

반응형

'spring > Entity' 카테고리의 다른 글

SprignBoot H2DB 설정  (0) 2022.04.21
Entity Listener - ②  (0) 2022.04.19
Entity  (0) 2022.04.18