[JPA] @MappedSuperclass
📌 목차
- 상속 관계 매핑
- @MappedSuperclass
- 실전 예제 - 4. 상속 관계 매핑
✔ @MappedSuperclass
MappedSuperclass는 공통매핑 정보가 필요한 경우 사용이 된다. 대표적인 예로는 DB 테이블이 다르지만 부모 클래스의 속성만 하위 구현체에서 물려받아 사용하고 싶은 경우 사용이 된다.
✅ 공통 엔티티가 없다 가정
@Entity
public class Member {
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
}
@Entity
public class Item {
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
}
다른 엔티티는 중략 하였습니다.
만약 DBA가 생성자, 생성일, 정의자, 정의일에 대한 컬럼을 추가해달라는 요구사항이 있다 가정하자. 만약 공통적으로 해결 할 수 있는 부분이 존재하지 않는다면 각각의 모든 클래스에 해당 4개의 컬럼을 추가해줘야 할 것이다.
✅ 공통 엔티티 생성
@MappedSuperclass // 매핑 정보에 대한 부분만 받는 엔티티
public abstract class BaseEntity {
/*
컬럼명을 지정하여 사용하는 것도 가능하다.
@Column(name = "INSERT_MEMBER")
private String createdBy;
*/
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
//.. Getter, Setter 중략
}
위처럼 @MappedSuperclass 어노테이션을 선언하면 해당 엔티티를 상속 받는 하위 구현체들에게 공통적인 매핑 정보를 제공 할 수 있다.
✅ 상속 관계 설정
// @Entity
public class Member extends BaseEntity { }
public class Item extends BaseEntity { }
Member, Item 엔티티는 BaseEntity를 상속한다.
✅ 호출부
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member member = new Member();
member.setUsername("user1");
member.setCreatedBy("ymkim");
member.setCreatedDate(LocalDateTime.now());
em.persist(member);
em.flush();
em.clear();
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
현재 Member 엔티티는 BaseEntity를 상속하여 생성일, 생성자를 셋팅하고 있습니다. 출력 결과를 한번 살펴보겠습니다.
🖨️ 출력 결과
Hibernate:
create table Item (
DTYPE varchar(31) not null,
id bigint not null,
createdBy varchar(255),
createdDate timestamp,
lastModifiedBy varchar(255),
lastModifiedDate timestamp,
name varchar(255),
price integer not null,
primary key (id)
)
Hibernate:
create table Member (
MEMBER_ID bigint not null,
createdBy varchar(255),
createdDate timestamp,
lastModifiedBy varchar(255),
lastModifiedDate timestamp,
USERNAME varchar(255),
LOCKER_ID bigint,
TEAM_ID bigint,
primary key (MEMBER_ID)
)
- 공통 정보 필드가 생성됨.
🔥 @MappedSuperclass 특징-1
- 상속관계 매핑, 엔티티가 아니다.
- 테이블과의 매핑은 불가능하다.
- 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공
- 조회, 검색 불가 (em.find(BaseEntity))
- 직접 생성해서 사용할 일이 없으므로 추상 클래스 권장.
// 조회 불가능 예시
em.find(BaseEntity.class, 중략)
🔥 @MappedSuperclass 특징-2
- 테이블과 관계가 없고 단순히 엔티티가 공통으로 사용하는 매핑정보를 모은다.
- 주로 등록일, 수정일, 등록자 등의 공통 정보를 모을 때 사용.
- @Entity 클래스는 @Entity나 @MappedSuperclass로 지정한 클래스만 상속 가능.
⚡ 결론
@MappedSupperclass를 사용하는 이유는 자바에서의 상속과 마찬가지로, 공통적인 특징(속성)을 하위 클래스에서 물려받아 사용하는 경우 사용한다 생각하자.
댓글남기기