[JPA, MappedSuperClass] BaseEntity를 만들어 Entity마다 중복되는 공통 필드의 중복을 없애자.

당근박쥐·2024년 5월 9일
0

문제 상황

아래는 UserEntity 코드이다. 25번~28번 라인쪽을 보면

created_at, updated_at를 가지고 있는데, 이 두 필드는 UserEntity뿐만 아니라 FriendEntity, LogEntity와 같은 모든 Entity에 공통으로 들어가게 될 필드이다.
유지보수를 위해 created_at, updated_at와 같은 공통된 필드를 가지고 있는 BaseEntity를 만들고 UserEntity에서 이를 상속받아 사용할 수 있다.

BaseEntity 코드

package carrotbat410.lol.entity;

import jakarta.persistence.MappedSuperclass;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

@MappedSuperclass
public abstract class BaseEntity {

    @CreationTimestamp
    private LocalDateTime created_at;
    @UpdateTimestamp
    private LocalDateTime updated_at;

    public BaseEntity() {
        this.updated_at = LocalDateTime.now();
    }

}

공통 필드를 가지는 BaseEntity를 만들고, @MappedSuperclass을 붙여준다.
이떄 직접 생성해서 사용할 일은 없으므로, 추상 클래스로 만드는것을 권장한다.

UserEntity 코드

package carrotbat410.lol.entity;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Getter
@Table(name = "users")
public class UserEntity extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String username;
    private String password;
    private String role;

    public UserEntity(String username, String password, String role) {
        this.username = username;
        this.password = password;
        this.role = role;
    }
}

만든 BaseEntity를 상속받으면 된다.
목적이였던 공통 필드가 중복되는 문제를 해결하였다. 다른 Entity에서는 상속만 받으면 된다.

실행된 ddl

Hibernate: 
    drop table if exists users
Hibernate: 
    create table users (
        id integer not null auto_increment,
        created_at datetime(6),
        updated_at datetime(6),
        password varchar(255),
        role varchar(255),
        username varchar(255),
        primary key (id)
    ) engine=InnoDB

created_at, updated_at 컬럼이 잘 생성된 걸 확인할 수 있다.

정리

  • 상속관계 매핑이 아니다.
  • @MappedSuperclass가 선언되어 있는 클래스는 엔티티가 아니다. 당연히 테이블과 매핑도 안된다.
  • 단순히 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공한다.
  • 조회, 검색이 불가하다. 부모 타입으로 조회하는 것이 불가능하다는 이야기.(em.find(BaseEntity) 불가능)
  • 직접 생성해서 사용할 일이 없으므로 추상 클래스로 만드는 것을 권장한다.
  • 테이블과 관계가 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
  • 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용한다.
  • 참고: JPA에서 @Entity 클래스는 @Entity나 @MappedSuperclass로 지정한 클래스만 상속할 수 있다.

출처: https://www.inflearn.com/course/ORM-JPA-Basic

profile
Starting the day with "git pull," it's good for mental health.

0개의 댓글