@MappedSuperclass

cw k·2022년 3월 14일
0

Java

목록 보기
2/2
post-thumbnail

@MappedSuperclass??

예전에 스프링부트와 AWS로 혼자 구현하는 웹서비스 라는 책을 볼때 다음과 같은 코드가 있었다.

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {
    @CreatedDate // Entity가 생성되어 저장될 떄 시간이 자동저장
    private LocalDateTime createdDate;

    @LastModifiedDate // 조회한 Entity의 값이 변경될때 시간이 자동저장
    private LocalDateTime modifiedDate;
}

출처 : 스프링부트와 AWS로 혼자 구현하는 웹서비스

그때는 그냥 넘어갔는데 이번에 개인프로젝트를 진행하며 생성, 수정날짜 등의 데이터를 생성할때 기존소스를 가져다 쓰는과정에서 @MappedSuperclass가 무슨역할인지 알아보기위해 포스팅을 작성한다.

공식문서 설명

매핑 정보가 상속되는 엔티티에 적용되는 클래스를 지정합니다. 매핑된 슈퍼클래스는 별도의 테이블이 정의되어 있지 않습니다.

MappedSuperclass 애노테이션으로 지정된 클래스는 매핑된 슈퍼클래스 자체에 대한 테이블이 없으므로 매핑이 하위 클래스에만 적용된다는 점을 제외하고 엔티티와 동일한 방식으로 매핑될 수 있습니다. 하위 클래스에 적용되면 상속된 매핑이 하위 클래스 테이블의 컨텍스트에 적용됩니다. 매핑 정보는 AttributeOverride 및 AssociationOverride 애노테이션 또는 해당 XML 요소를 사용하여 이러한 하위 클래스에서 재정의할 수 있습니다.

	@MappedSuperclass
    public class Employee {

        @Id protected Integer empId;
        @Version protected Integer version;
        @ManyToOne @JoinColumn(name="ADDR")
        protected Address address;

        public Integer getEmpId() { ... }
        public void setEmpId(Integer id) { ... }
        public Address getAddress() { ... }
        public void setAddress(Address addr) { ... }
    }

    // Default table is FTEMPLOYEE table
    @Entity
    public class FTEmployee extends Employee {

        // Inherited empId field mapped to FTEMPLOYEE.EMPID
        // Inherited version field mapped to FTEMPLOYEE.VERSION
        // Inherited address field mapped to FTEMPLOYEE.ADDR fk

        // Defaults to FTEMPLOYEE.SALARY
        protected Integer salary;

        public FTEmployee() {}

        public Integer getSalary() { ... }

        public void setSalary(Integer salary) { ... }
    }

    @Entity @Table(name="PT_EMP")
    @AssociationOverride(
        name="address", 
        joincolumns=@JoinColumn(name="ADDR_ID"))
    public class PartTimeEmployee extends Employee {

        // Inherited empId field mapped to PT_EMP.EMPID
        // Inherited version field mapped to PT_EMP.VERSION
        // address field mapping overridden to PT_EMP.ADDR_ID fk
        @Column(name="WAGE")
        protected Float hourlyWage;

        public PartTimeEmployee() {}

        public Float getHourlyWage() { ... }
        public void setHourlyWage(Float wage) { ... }
    }

출처: https://docs.oracle.com/javaee/7/api/javax/persistence/MappedSuperclass.html

분석

javax.pertistence@Entity는 따로 @Table 애노테이션에 테이블 이름을 지정하지 않으면
기본적으로 클래스명을 테이블로 지정하게 된다.

하지만 @MappedSuperclass 공식문서 설명과 같이 테이블에 대한 정의를 하지 않는다.

애노테이션 이름 그대로 자식클래스에 매핑되는 부모클래스의 역할만 한다고 보면된다.

위 코드에서 @MappedSuperclass로 지정한 Employee 가 있고 Employee 클래스에는 empId, version, address 3개의 속성을 갖고 있다.

FTEmployeePartTimeEmployeeEmployee를 상속받는데 주석에나와있듯이 Employee에 지정한 3개의 필드가 FTEmployeePartTimeEmployee 의 필드로 매핑된다.

PartTimeEmployee 와 같이 @AssociationOverride 를 지정해 이름이나 조인하는 컬럼등을 따로 지정할 수도 있다.

활용

쓰임새는 보통 여러 엔티티에서 공통적으로 사용하는 반복되는 속성들을 묶어관리한다고 보면된다. (ex: 생성일, 수정일 등)

@MappedSuperclass 가 지정된 클래스를 상속받는 엔티티는 @MappedSuperclass 에 지정한 속성들을 사용할 수 있다.

아래는 위에 첨부한@MappedSuperclass로 지정한 BaseEntity 를 상속받는 Member 엔티티이다.

@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

    private String password;

    @Column(unique = true)
    private String email;

    private String name;

    private String imageUrl;

    @NotNull
    @Enumerated(EnumType.STRING)
    private AuthProvider provider; // ex: google, naver, github ..

    private String providerId;

    @Enumerated(EnumType.STRING)
    private Role role;
}

어플리케이션을 구동하고 로그을 확인해보면 다음과 같이 @MappedSuperclass 로 지정한 BaseEntity의 2가지 속성을 받아오는 것을 확인할 수 있다.

0개의 댓글