-> 블로그 이전

[JPA] @MappedSuperClass

2022. 7. 5. 14:27Language`/JPA

 

[JPA] 상속 관계

일반적으로 관계형 DB에서는 객체지향 언어에서 다루는 "상속"이라는 개념이 존재하지 않는다 그대신 "슈퍼타입 - 서브타입"같은 모델링 기법을 통해서 우회적으로 상속을 구현할 수 있다 슈퍼

cs-ssupport.tistory.com

상속 관계의 기본적으로 JOINED 전략을 사용하면 Super Type & Sub Type 모두 DB Table과 매핑되었다

 

하지만 여기서 부모 클래스는 DB Table과 매핑하지 않고 자식 클래스에게 속성만 물려주고 싶다면 @MappedSuperClass를 사용하면 된다

 

@MappedSuperClass는 단순히 "필드 정보"를 상속할 목적으로만 사용하는 것이다

 

예를 들어서 거의 모든 테이블에 필요한 {생성 날짜 / 생성한 사람 / 수정 날짜 / 수정한 사람} 필드의 경우 모든 테이블에 각각 적어주면 굉장히 비효율적이기 떄문에 @MappedSuperClass로 지정해서 extends를 통해서 사용할 수 있게 하면 된다

@MappedSuperClass

Inflearn : 자바 ORM 표준 JPA 프로그래밍 - 기본편(김영한)

 

abstract CommonField - 공통 속성 @MappedSuperClass

@MappedSuperclass
public abstract class CommonField {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
}

Member (extends CommonField)

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "member")
public class Member extends CommonField{
    private String email;
}

Seller (extends CommonField)

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "seller")
public class Seller extends CommonField{
    private String shopName;
}

이렇게 공통 속성(필드)는 따로 @MappedSuperClass로 구현하고 이 공통 속성들을 사용할 Entity들은 공통 속성 class를 extends해주기만 하면 된다

MappedSuperClass의 각 필드(id, name)이 골고루 매핑된 것을 확인할 수 있다

>> 그런데 id, name과 같은 필드이름을 변경해서 각각 매핑할 수는 없을까?


@AttributeOverrides & @AttributeOverride

만약 MappedSuperClass에 존재하는 필드에 대해서 재정의해서 사용하고 싶으면 @AttributeOverride를 사용하면 되고, 재정의할 필드가 여러개면 @AttributeOverrides 내부에서 각 필드를 @AttributeOverride를 통해서 재정의하면 된다

@AttributeOverride(name = "id", column = @Column(name = "member_id"))
public class Member extends CommonField{
    private String email;
}
@AttributeOverride(name = "id", column = @Column(name = "seller_id"))
public class Seller extends CommonField{
    private String shopName;
}

이처럼 각 id가 설정한 이름대로 매핑이 된 것을 확인할 수 있다

 

이제 id/name 둘다 서로 다른 이름으로 매핑해보자
@AttributeOverrides({
        @AttributeOverride(name = "id", column = @Column(name = "member_id")),
        @AttributeOverride(name = "name", column = @Column(name = "member_name"))
})
public class Member extends CommonField{
    private String email;
}
@AttributeOverrides({
        @AttributeOverride(name = "id", column = @Column(name = "seller_id")),
        @AttributeOverride(name = "name", column = @Column(name = "seller_name"))
})
public class Seller extends CommonField{
    private String shopName;
}


@MappedSuperClass의 특징

1. 테이블 매핑과는 전혀 관련이 없고 공통 속성들을 @Entity에 물려주기 위해서 사용한다

2. @MappedSuperClassEntity가 아니기 때문에 당연히 em.find()나 JPQL을 통해서 사용할 수 없다

3. 결론적으로 @MapperSuperClass는 직접 사용할 일이 없기 때문에 abstract class로 만드는 것이 낫다