[Spring Data JPA] BaseEntity

mo!n·2025년 2월 26일

이전 프로젝트에서 테이블의 공통 칼럼을 BaseEntity로 빼고, extends로 다른 Entity에 삽입해서 사용하는 방식을 접한적이 있었다. 새로운 프로젝트에서도 그 방법으로 Entity를 생성하는데 자꾸 오류가 나서 뭐가 문제인지 찾아보도록하자.

BaseEntity

Spring Boot에서 Entity를 만들다보면 중복되는 요소가 분명히 존재한다. 이를 해결하기 위해 사용되는것이 BaseEntity이다.

@MappedSuperClass

BaseEntity는 이름만 Entity이지 실제로 Entity처럼 테이블이 따로 존재하지 않는다.따라서 본인의 테이블이 생성되지 않고 Entity끼리만 상속해줄 수 있도록 @MappedSuperClass 어노테이션을 이용 해야한다.

// Base Entity
@MappedSuperclass // base entity에는 @Entity가 오면 안되고 해당 어노테이션을 써야한다.
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "created_at")
    @CreationTimestamp
    private LocalDateTime createdAt;

    @Column(name = "updated_at")
    @UpdateTimestamp
    private LocalDateTime updatedAt;
}

위의 공통 부분만 뽑아놓은 Base Entity를 필요한 Entity에 extends해서 사용하면 된다.

// User Entity
@Entity
@Table(name = "user")
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class User extends BaseEntity {
    @Column(name = "email")
    private String email;

    @Column(name = "name")
    private String name;

    @Column(name = "password")
    private String password;

    @Column(name = "is_withdrawal")
    private Boolean isWithdrawal;

    @Column(name = "authority_id")
    private Long authorityId;

}

appplication.yml 설정

그리고 yml에서 hibernate ddl-auto설정을 create로 해야 새로 생성, 이후에 update로 수정하거나, none으로 변경해서 수동으로 table을 생성하는 방법을 사용해도 된다.

spring:
  application:
    name: TripTogether
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/trip_together
    username: root
    password: *****
  jpa:
    hibernate:
      ddl-auto: create # -> update로 변경
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect

그러면 처음부터 update로 해놔도 되는 거 아닌가?🤔

spring:
  jpa:
    hibernate:
      ddl-auto: update
  • 기존의 테이블이 삭제되지 않고 유지
  • 새로운 엔티티가 추가되면 그에 맞는 테이블이 자동 생성
  • 기존 테이블에 필드가 추가되면 자동으로 칼럼이 추가
  • 그러나, 기존 칼럼이 삭제되거나, 타입이 변경되지는 않는다.

개발 단계에서 빠르게 테이블을 생성하거나 수정이 쉽기 때문에(어플리케이션을 재시작하는 경우 수정, 생성) 초기에 update로 시작해도 된다!
그러나, 운영환경에서는 예상치 못한 변경이 DB에 반영되므로 none으로 변경해야함

따라서, update로 해도 상관은 없지만 프로젝트 초기에는 기존 칼럼의 삭제나 타입 변동등 수정 가능성이 많기 때문에 create로 시작하고 update로 변경을 하는 것이 좋다.

결론,

내 프로젝트의 경우에는 BaseEntity@Entity 어노테이션이 들어간 것이 문제였다.
Base Entity에는 @Entity 를 적지 않고 @MappedSuperclass를 기입하고, 그를 상속받는 다른 Entity에는 @Entity 어노테이션을 붙여 명시해주도록 하자.

profile
백엔드 굴리는 감자 🥔

0개의 댓글