들어가며
Member, Order, Board 등 다양한 엔티티를 생성하여 사용하다보면, 반복되는 공통 속성이 존재하게 됩니다. 예를 들면, 생성일, 수정일, 식별자 등이 있으며, 보통 하나로 묶어 BaseEntity를 생성하여 각 엔티티가 상속받을 수 있도록 구현하며 사용하곤 합니다.
본 포스팅에는 공통 속성을 하나로 묶어 BaseEntity라는 부모 클래스를 생성하는 내용을 소개합니다.
📌 공통 속성
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private LocalDateTime createDate;
private LocalDateTime updateDate;
}
일반적으로 각 엔티티에는 공통 속성이 존재하게 됩니다. 저의 경우에는 생성일, 수정일, 식별자가 공통 속성에 해당하는 편입니다. 따라서 이러한 코드를 하나의 클래스에 모두 담아 정의하여 사용하는 방식을 사용합니다.
BaseEntity 클래스를 생성하여 위에서 말한대로 공통 속성을 담고, 엔티티가 상속받을 수 있도록 하면, 공통 속성에 대한 추상화도 가능하며, 코드 중복을 줄일 수 있습니다.
📌 BaseEntity 생성하기
@Getter
@MappedSuperclass
@SuperBuilder
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@CreatedDate
@Column(updatable = false)
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime updateDate;
}
먼저, abstract class로 만드는 이유는, 해당 클래스를 직접 인스턴스화하여 사용할 이유가 없기 때문입니다. 반드시, 자식 클래스에서 상속받아 사용할 수 있도록 abstract 클래스로 생성해주었습니다.
@MappedSuperclass
BaseEntity를 상속받은 자식 클래스에게, 부모 클래스의 매핑 정보를 모두 제공해주는 어노테이션입니다. 해당 어노테이션은 Entity로 인식되지 않으며, 데이터베이스에 테이블이 생성되지 않습니다.
이 어노테이션으로 인하여, 상속받은 자식 클래스는 모두 공통 속성을 지니게 됩니다.
@SuperBuilder
Builder 패턴을 위하여 Lombok의 @Builder를 통해 자식 클래스를 생성해주는 과정에서, 당연히 부모 클래스에 속하는 공통 속성도 함께 생성되어야 합니다. 따라서, Lombok에서는 @SuperBuilder라는 어노테이션을 제공합니다.
해당 어노테이션을 사용하려면, 부모와 자식 클래스에 모두 붙여 사용해주어야 합니다.
@NoArgsConstructor
No Args, 즉 매개변수가 없는 기본 생성자를 생성해주는 어노테이션입니다. 별도로 생성자를 정의해주지 않아도 이 어노테이션을 붙이면 자동으로 생성됩니다. 물론, 기본 생성자는 명시적으로 정의해두지 않아도 자동 생성됩니다. 그러나, 별도로 매개변수가 있는 생성자를 이미 정의해둔 상황에는, 기본 생성자는 자동으로 생성되지 않습니다.
따라서, 이 어노테이션을 붙여주면, 이미 정의해둔 다른 생성자가 존재하더라도 기본 생성자를 생성해주어 사용할 수 있게 됩니다.
@EntityListeners(AuditingEntityListener.class)
JPA Auditing 기능을 사용하려면, application 클래스에 @EnableJpaAuditing을 붙여주어야 사용이 가능합니다.
AuditingEntityListener 클래스는 엔티티의 생성, 수정, 삭제 등의 이벤트가 발생하였을 때, 이와 같은 엔티티의 변경 사항을 Audit(감사)하기 위한 클래스입니다. 해당 어노테이션으로 리스너 클래스를 등록하여, 엔티티에 대한 이벤트가 발생하였을 때, 이벤트에 대한 처리를 진행할 수 있습니다.
따라서, @CreateDate와 @LastModifiedDate를 적용하여, 엔티티의 생성일과 마지막 수정일을 간편하게 관리할 수 있습니다.
📌 정리
이렇게 공통 속성을 담은 BaseEntity는 엔티티별로 상속받아 사용하면 완료입니다.
@Getter
@Entity
@SuperBuilder
@NoArgsConstructor
public class Member extends BaseEntity {
private String username;
private String password;
}
포스팅 내용에 오류가 있는 경우, 댓글로 남겨주시면 감사드리겠습니다. 😃
파이팅!