의문
Realworld 프로젝트를 시작하면서 엔티티 정의와 매핑을 하기 시작했다.
모든 테이블에 공통적으로 들어갈 (Id, createdAt, updatedAt)
속성은 강의에서 배운대로 BaseEntity
로 뽑아내었고 개발 편의성이나 개념적으로도 타당하다고 생각했다.
![](https://blog.kakaocdn.net/dn/PWY34/btsjJSXDMBW/W9WFB1kwXBn3LRAQRQHTpK/img.png)
그런데, 프로젝트 API Response format Users
와 Profile
을 보면 상당부분이 비슷함을 알 수 있다.
반환할 때 DTO를 반환할 것이기 때문에 크게 상관이 없긴 하지만, 문제는 엔티티 매핑할 때 발생한다.
![](https://blog.kakaocdn.net/dn/baVygW/btsjRgQbd9A/HsmzgLkkYGqv2wQ50mE6n1/img.png)
단위가 더 큰 User
클래스를 엔티티로 만들고 사용하려 했지만, 다른 API들에서는 대부분 Profile
을 내려주고 있다.
이럴 때는 Profile
에 해당하는 클래스를 그냥 하나 만들어주고 User
쪽에서 @Embedded
로 받는 편이 훨씬 편하기 때문에 이렇게 진행하려 했다.
여기서 의문점이.. @MappedSuperclass
와 @Embeddable
의 동작이 비슷해 보이는데 정확한 차이점이 무엇인지 궁금해서 알아봤다.
@MappedSuperclass
- 부모클래스의 클래스 레벨에 붙는 어노테이션으로, 부모클래스의 매핑 정보를 자식클래스에게 제공하기 위해 사용한다.
- 부모클래스 자체는 엔티티가 아니며, 테이블로 매핑도 되지 않는다.
- 테이블과 관계 없이 여러 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
- 어쨋든 근본은 상속이기 때문에 is-a관계를 만족시켜야한다.
@Getter
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@Getter
@NoArgsConstructor
@Entity
public class User extends BaseEntity {
private String password;
private String email;
private String bio;
private String image;
}
@Embeddable
- 클래스 레벨에 붙는 어노테이션으로, 새로운 값 타입을 직접 정의해서 사용할 때 사용한다.
- 마찬가지로 엔티티가 아니며, 테이블로 매핑도 되지않는다.
- 테이블과 관계없이 여러 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
- 상속과 관계없이 사용한다.
@Embeddable
public class Profile {
private String email;
private String bio;
private String image;
}
@Getter
@NoArgsConstructor
@Entity
public class User extends BaseEntity {
...
@Embedded
private Profile profile;
}
정리
@MappedSuperclass
는 어쨋거나 상속(is-a)에 사용된다.
@Embeddable
은 어쨋거나 상속과 관련없이 사용된다.- 상속이 아닌 위임(delegate)를 이용한 방법으로, 객체마다의 역할에 충실하게 할 수 있다.
- 상속은 부모클래스에게 과하게 의존하는 경향이 있기 때문에 is-a관계이면서 필요할 때가 아니면 지양해야한다.
BaseEntity
의 경우엔 is-a관계를 만족하고, 엔티티의 중복된 필드를 재사용하기 위한 목적이 크기 때문에@MappedSuperclass
이 맞다.
Profile
의 경우엔User
와 is-a관계가 아니고, 중복된 필드를 재사용하기 위한 목적 뿐 아니라 비지니스로직에서도 다른 의미를 갖고 있으므로@Embeddable
이 맞다.
Uploaded by N2T
(23.06.13 06:10)에 작성된 글 입니다.