엔티티를 구현하다보면 여러 엔티티의 공통된 필드를 분리하고 싶은 경우가 있다. 이 때 사용할 수 있는 어노테이션을 정리해보려고 한다. 엔티티를 분리할 때도 상속과 조합을 사용할 수 있다. 이 때 사용할 수 있는 각 어노테이션은 다음과 같다.

  • 상속: @MappedSuperclass
  • 조합: @Embeddable, @Embedded

@MappedSuperclass

일반적으로 상속 관계 매핑 전략에서는 부모와 자식 둘 다 테이블에 매핑된다. 그러므로 상속관계에서 부모와 자식 둘 다 엔티티이어야 한다. 하지만 엔티티마다 공통적으로 필요한 테이블 정보가 있을 수 있다. 예를 들어, id, 생성 시간, 수정 시간 등이 있다. 이 때 부모 클래스는 단순히 자식 클래스에게 매핑 정보만 제공해주고 자신은 엔티티일 필요가 없다. 부모 클래스가 엔티티가 아닐 때 상속을 해주어야 하는 경우 필요한 어노테이션이 @MappedSuperclass 이다.

@MappedSuperclass
public abstract class BaseEntity {
  // ...
}
@Entity
public class User extends BaseEntity {
  // ...
}

@Embeddable@Embedded

엔티티를 구현하다보면 공통적인 부분을 제거하기 위해 객체를 따로 분리하고 싶은 경우가 있다. 분리한 객체의 필드 정보를 테이블에 매핑하고 싶을 때 사용하는 어노테이션이다.

  • @Embeddable: 분리한 클래스 위에 선언한다.
  • @Embedded: 분리한 클래스를 사용하는 엔티티 필드 위에 선언한다.
@Embeddable
public class Name {
  private final String firstName;
  private final String lastName;
  // ...
}
@Entity
public class User {

  @Embedded
  private final Name userName;
  // ...
}

@AttributeOverride

@MappedSuperclass를 통해 상속 받은 경우나 @Embedded를 통해 다른 객체를 필드에 선언한 경우 해당 엔티티에서는 다른 컬럼명을 사용하고 싶을 때가 있다. 이러한 경우에 사용할 수 있는 어노테이션이다.

@Entity
@AttributeOverride(name = "id", column = @Column(name = "article_id"))
public class Article extends BaseEntity {
  // ...
}

여러 개의 정보를 바꾸고 싶을 때 방법은 아래와 같다.

@Entity
@AttributeOverrides({
  @AttributeOverride(name = "id", column = @Column(name = "article_id")),
  @AttributeOverride(name = "createTime" column = @Column(name = "article_create_time"))
})
public class Article extends BaseEntity {
  // ...
}
@Enitty
public class Author {

  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name = "firstName", column = @Column(name = "author_first_name")),
    @AttributeOverride(name = "lastName", column = @Column(name = "author_last_name"))
  })
  private final Name authorName;
  // ...
}