Spring/Annotation

[JPA] @MappedSuperclass

s_y_130 2023. 2. 3. 14:40

@MappedSuperclass


@MappedSuperclass는 상속관계 매핑과는 관련이 없다.

객체의 입장에서 공통 매핑 정보가 필요할 때 사용한다.

  • id, name은 객체의 입장에서 볼 때 계속 나온다.
  • 이렇게 공통 매핑 정보가 필요할 때, 부모 클래스에 선언하고 속성만 상속 받아서 사용하고 싶을 때 @MappedSuperclass를 사용한다.
  • 정확히는 DB의 상속관계 매핑과는 관련이 없다. 아래에 보면 DB는 매핑 정보 다 따로 쓰고 있다. 

 

 

 

 

예를 들어 모든 클래스는 생성 시간(createdDate)라는 속성을 가져야 한다고 가정하자.

 

모든 클래스마다 직접 createdDate라는 필드를 붙여줄 수 있지만, createdDate라는 필드를 가진 추상 클래스(혹은 일반 클래스)를 만들어 이를 다른 클래스들이 상속받도록 하는 것이 좀 더 효과적이다.

 

즉 이는 공통된 필드를 사용하기 위한 상속을 받은 것이지, 부모와 자식의 관계 혹은 is-a 관계이기 때문에 상속을 받은 것이 아니다.

DB상에서는 모든 테이블에 createdDate가 들어있는 구조로 설계될 것이다.

 

@MappedSuperclass는 위와 같이 공통된 매핑 정보가 필요한 경우에 사용할 수 있다.

 

 

 

예시


모든 클래스들은 다음 정보를 공통으로 가지고 있어야 한다고 가정해보자.

  • 누가 생성했는지 (createdBy)
  • 언제 생성되었는지 (createdDate)
  • 누가 마지막으로 수정하였는지 (lastModifiedBy)
  • 마지막으로 수정된 날짜가 언제인지 (lastModifiedDate)
1
2
3
4
5
6
7
8
@MappedSuperclass
public class BaseEntity {
 
    private String createdBy;
    private LocalDateTime createdDate;
    private String lastModifiedBy;
    private LocalDateTime lastModifiedDate;
}
cs

 

BaseEntity 상속

1
2
3
4
5
6
7
8
9
@Entity
public class Member extends BaseEntity{
 
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
 
    private String username;
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn//기본값이 DTYPE
public class Item extends BaseEntity{
 
    @Id @GeneratedValue
    @Column(name = "ITEM_ID")
    private Long id;
 
    private String name;
 
    private int price;
}
cs

 

모든 클래스에 추가해주어야 할 속성을 BaseEntity로 만들어서 이를 상속받도록 하였다.

 

해당 코드를 실행하면 생성되는 DB는 다음과 같다.

 

 

 

 

@MappedSuperclass 정리


  • 상속관계 매핑이 아니다.
  • @MappedSuperclass가 선언되어 있는 클래스는 엔티티가 아니다.
  • 엔티티가 아니기 때문에 테이블과 매핑되지 않는다.
  • 부모 클래스는 상속받는 자식 클래스에게 매핑 정보만 제공한다.
  • 조회, 검색이 불가능하다. 부모 타입으로 조회하는 것이 불가능하다는 이야기.(em.find(BaseEntity) 불가능)
  • 직접 생성해서 사용할 일이 없으므로 추상 클래스로 사용하는 것을 권장한다.
  • 테이블과 관계 없이, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
  • 주로 등록일, 수정자, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용한다.
  • @Entity 클래스는 엔티티나 @MappedSuperclass로 지정한 클래스만 상속이 가능하다.

 

 

 

참고


  • @Inheritance는 다형성을 위한 상속

  • @MappedSuperclass는 코드 재사용을 위한 상속을

  • @Embedded, @Embeddable은 합성을 구현할 때 사용한다.