2022. 7. 5. 14:27ㆍLanguage`/JPA
상속 관계의 기본적으로 JOINED 전략을 사용하면 Super Type & Sub Type 모두 DB Table과 매핑되었다
하지만 여기서 부모 클래스는 DB Table과 매핑하지 않고 자식 클래스에게 속성만 물려주고 싶다면 @MappedSuperClass를 사용하면 된다
@MappedSuperClass는 단순히 "필드 정보"를 상속할 목적으로만 사용하는 것이다
예를 들어서 거의 모든 테이블에 필요한 {생성 날짜 / 생성한 사람 / 수정 날짜 / 수정한 사람} 필드의 경우 모든 테이블에 각각 적어주면 굉장히 비효율적이기 떄문에 @MappedSuperClass로 지정해서 extends를 통해서 사용할 수 있게 하면 된다
@MappedSuperClass
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. @MappedSuperClass는 Entity가 아니기 때문에 당연히 em.find()나 JPQL을 통해서 사용할 수 없다
3. 결론적으로 @MapperSuperClass는 직접 사용할 일이 없기 때문에 abstract class로 만드는 것이 낫다