MappedSuperClass, JPA Auditing

June·2022년 7월 13일
0

우테코

목록 보기
59/84

학습배경

create table answer
(
    created_at  datetime(6) not null,
	...
) engine=InnoDB

create table delete_history
(
	...
    create_date   datetime(6),
) engine=InnoDB

create table question
(
    created_at datetime(6)  not null,
	...
) engine=InnoDB

create table user
(
    created_at datetime(6) not null,
	...
) engine=InnoDB

여러 개의 엔티티가 있는데 공통적으로 객체가 생성된 시간을 저장할 필요가 있다. 현재 두 가지 문제가 있는 것이다.

  1. 각 엔티티마다 LocalDateTime createdAt을 붙여야 한다.
  2. 각 엔티티가 생성될 때 LocalDateTime createdAt = LocalDateTime.now()를 붙여야 한다. 생성은 그렇다치더라도 업데이트 될 때마다 갱신하는 것은 실수할 위험도 있다.

공통 속성 - @MappedSuperClass

공식 문서 링크

공식문서에 나와있듯이 새로운 테이블이 생기는 것이 아니다. 그래서 서로 관련이 없는 테이블들이지만 공통적인 속성이 필요할 때 사용할 수 있다.

Answer 엔티티가 BaseEntity를 상속받고 있는데, BaseEntity를 상속받는 엔티티들에는 해당 필드가 들어온다.

시간 자동 설정 - Auditing

@CreationTimestamp

미션을 진행하면서 Auditing이 잘되지 않아 써머랑 이야기를 나누었는데, 써머는 아예 Auditing을 하지 않았다고 했다. 그럼 어떻게 했냐고 물으니 @CreationTimestamp를 썼다고 했고, 난 그게 있는지 몰랐고 써머는 Auditing이 있는지 몰랐다.

@CreationTimestamp는 JPA의 구현체 중 하나인 하이버네이트에서 지원하는 어노테이션이다. 만약 나중 구현체를 바꾸게 된다면 코드의 변경이 더 필요하게 되므로 사용을 지양해야 한다

EntityListners

@CreatedDate를 붙이면 생성 날짜를 자동으로 매핑해준다.

하이버네이트 문서을 보면 엔티티에 이벤트가 발생했을 때 콜백을 처리하는 방법이라고 나와있다.

그래서 변경에 대해 감지를 하는 것을 설정해줘야 하는데 @EntityListner를 통해서 정할 수 있다.

@DataJpaTest

설정을 이렇게 해줬는데 Application에서 JPA와 관련있는 어노테이션을 바로 붙이는게 추상화 레벨이 맞지 않다는 느낌이 들었다.

그래서 @Configuration을 이용해서 관련 설정을 빼주었다.

이렇게 했더니 테스트코드에서 깨지는 문제가 있었다.

@DataJpaTest는 JPA와 관련된 컴포넌트들에만 집중하기 때문에 스프링 부트의 설정까지 가져오지 못했기 때문이다.

그래서 이렇게 직접 import를 해줘야 한다.

참고

오찌

https://sokdak-sokdak.tistory.com/

https://github.com/spring-projects/spring-boot/issues/13337

미션

0개의 댓글