[Spring Boot] Spring Data JPA에서 BaseEntity 사용하기
BaseEntity란?
Spring Boot 내에서 코드를 작성하다 보면 정보가 중복되는 경우가 종종 발생합니다.
이러한 경우를 손쉽게 해결해 주는 방법이 바로 BaseEntity입니다.
아래 코드를 보면 Student와 Professor 클래스 내 정보를 살펴보면,
createdBy와 createdDate에서 공통 정보가 발생합니다.
물론 하나하나씩 별도로 작성해 주어도 문제는 없지만, 중복된 것처럼 보일 수 있기에 이를 한 곳에 공통으로 매핑해 주는 것이 좋습니다.
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;
private String name;
// 공통 컬럼
private String createdBy;
private LocalDateTime createdDate;
}
@Entity
public class Professor {
@Id
@GeneratedValue
private Long id;
private String name;
// 공통 컬럼
private String createdBy;
private LocalDateTime createdDate;
}
Spring Boot를 실행해 주고 H2 데이터베이스를 접속해 보면 아래와 같이 테이블이 생성되어 있습니다.
저희는 좀 더 효율적으로 BaseEntity를 통해서 코드를 개선해 보겠습니다.
BaseEntity 적용해 보기
먼저 같은 패키지 내에 아래와 같이 BaseEntity 클래스를 생성해 주었습니다.
클래스를 생성해 준 후, 아까 중복되었던 정보인 createdBy와 createdDate를 BaseEntity 클래스 내에 작성해 줍니다.
@MappedSuperclass
public abstract class BaseEntity {
private String createdBy;
private LocalDateTime createdDate;
}
여기서 잠깐,
@MappedSuperClass란?
BaseEntity는 사실 클래스명만 BaseEntity이고, 실제 Entity가 아닙니다.
Entity 클래스는 Entity 클래스끼리만 상속받을 수 있으므로 따라서 엔티티나 @MappedSuperclass 어노테이션을 작성해주어야 합니다.
다시 본론으로 넘어가서 Student와 Professor 클래스에서 중복되었던 데이터를 제거해 준 후,
extends 키워드를 통해서 BaseEntity로 확장을 해줍니다.
@Entity
public class Student extends BaseEntity {
@Id
@GeneratedValue
private Long id;
private String name;
}
@Entity
public class Professor extends BaseEntity {
@Id
@GeneratedValue
private Long id;
private String name;
}
코드를 깔끔하게 수정 후 다시 H2 데이터베이스를 실행하여 쿼리문을 입력한 결과,
테이블의 속성은 동일하게 나타납니다.
@MappedSuperclass에 대하여 알아두어야 할 점
@MappedSuperclass 어노테이션은 테이블과 관계가 없고, 공통 매핑 정보를 모으는 역할을 합니다.
단순히 부모 클래스를 상속받는 자식 클래스에게 매핑 정보만 제공하는 것이죠.
그러므로, 이 어노테이션을 사용한 클래스는 조회와 검색이 불가능 합니다.
ex) em.find(BaseEntity) 사용 불가
또한, 직접 생성해서 사용할 경우가 없므로 추상 클래스를 권장합니다.
출처 : 인프런 김영한 - 자바 ORM 표준 JPA 프로그래밍(기본편)