Spring-JPA(@MappedSuperClass,@EntityListener)

2021. 3. 23. 01:12Spring

Spring-JPA Annotation(@MappedSuperclass, @EntityListeners)

@Getter
@Setter
@MappedSuperclass // 상속했을 때, 컬럼으로 인식하게 합니다. 즉 이 timestamped 추상클래스를 상속한 클래스가 자동으로 생성시간과 수정 시간을 컬럼으로 잡도록 도와주는 녀석이다.
@EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정. memo class가 변화하는 거를 항상 이렇게 듣는다. 생성시간과 수정시간이 변화가 있으면 자동으로 업데이트 해주겠다는 뜻.
public abstract class Timestamped {

   @CreatedDate // 생성일자임을 나타냅니다.
   private LocalDateTime createdAt;

   @LastModifiedDate // 마지막 수정일자임을 나타냅니다.
   private LocalDateTime modifiedAt;


}

  • 여기서 createAt, modifiedAt은 왠만한 엔티티에서 공통으로 들어가는 Colum이기 때문에 따로 엔티티를 만들어서 다른 엔티티가 상속을 받게 만든다.
  • 하나의 예를 들어보면
    • 이러한 식으로 BaseEntity를 만들어서 다른 객체들이 상속을 받아 공통으로 사용할 수 있게 한다. 하지만 DB에서 보면 따로따로 Colum이 생기는걸 볼 수 있다.
    • 이 클래스는 Entity가 아니라, 맵핑 정보만 가지고 있는 SuperClass란 의미로 @MappedSuperclass로 선언한다.
    • 실제 DB에 저장되는 모습

@EntityListener

개요

  • Entity의 데이터 변경을 자동으로 반영하도록 설정한다.

AuditingEntityListener

  • Auditing?
    • 감시하다라는 뜻
  • Entity를 영속성 컨테스트에 저장하거나, 조회를 수정한 후 update 하는 경우에 자동으로 auditor, time을 맵핑하여 데이터 베이스에 넣도록 도와준다.
  • 스프링 부트의 엔트리 포인트인 실행 클래스에 @EnableJpaAuditing 을 적용하여 JPA Auditing을 활성화 해야한다.
  • 여기서는 다른 객체가 이걸 상속 받으면 그 객체의 데이터가 수정되면 그걸 캐치해서 modifiedAt을 변경하지만 사용자가 직접 클래스를 만들어서 넣어서 사용할 수 도 있다.@EntityListeners(DataDtoListener.class) // {} 를 통해서, 복수의 리스너를 등록할 수 있음
    @Entity
    public class DataDto() {
     
      @Id
      private long id;
     
      //...
    }

    public class DataDtoListener {
       
       @PostLoad
       public void postLoad(DataDto dto) {
           log.info("post load: {}", dto);
      }
       
       @PrePersist
       public void prePersist(DataDto dto) {
           log.info("pre persist: {}", dto);
      }
       
       @PostPersist
       public void postPersist(DataDto dto) {
           log.info("post persist: {}", dto);
      }
       
       @PreUpdate
       public void preUpdate(DataDto dto) {
           log.info("pre update: {}", dto);
      }
       
       @PostUpdate
       public void postUpdate(DataDto dto) {
           log.info("post update: {}", dto);
      }
       
       @PreRemove
       public void preRemove(DataDto dto) {
           log.info("pre remove: {}", dto);
      }
       
       @PostRemove
       public void postRemove(DataDto dto) {
           log.info("post remove: {}", dto);
      }
    }
  • EntityListener 클래스에 적용한 이벤트는 다음 시점에 호출된다
    • @PostLoad : 해당 엔티티를 새로 불러오거나 refresh 한 이후
    • @PrePersist : 해당 엔티티를 저장하기 이전
    • @PostPersist: 해당 엔티티를 저장한 이후
    • @PreUpdate : 해당 엔티티를 업데이트 하기 이전
    • @PostUpdate : 해당 엔티티를 업데이트 한 이후
    • @PreRemove : 해당 엔티티를 삭제하기 이전
    • @PostRemove : 해당 엔티티를 삭제한 이후

@CreateDate

개요

  • Entity 생성, 수정시 특정 필드를 자동으로 데이터베이스에 맵핑해주기 위해 사용함
  • Auditing 기능을 사용하려면, 위의 어노테이션을 사용해야한다.
    • @EnableJpaAuditing 이 필수적으로 SpringApplication 시작에 있어야 하고
  • Spring Data JPA에서 사용할 때는 이를 사용하는게 좋을듯

정리

  • 상속광계 매핑이 아니다.
  • @MappedSuperclass가 선언되어 있는 클래스는 엔티티가 아니다. 당연히 테이블과 매핑도 안된다.
  • 단순히 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공한다.
  • 조회, 검색이 불가하다. 부모 타입으로 조회하는 것이 불가능하다는 이야기.(em.find(BaseEntity) 불가능)
  • 직접 생성해서 사용할 일이 없으므로 추상 클래스로 만드는 것을 권장한다.
  • 테이블과 관계가 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
  • 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용한다.
  • 참고
    • JPA에서 @Entity 클래스는 @Entity나 @MappedSuperclass로 지정한 클래스만 상속할 수 있다.
    • 출처: https://ict-nroo.tistory.com/129 [개발자의 기록습관]

'Spring' 카테고리의 다른 글

[Spring] @Valid  (0) 2021.04.11
[Spring] Bcrypt로 암호화하기  (0) 2021.04.11
Spring으로 Token 받기  (0) 2021.04.11
spring jpa localtime between  (0) 2021.03.23
Spring으로 간단한 게시판 만들기  (0) 2018.11.12