About Embedded Type
Embedded란 JPA 표준에서 "객체 지향적인 방식으로 데이터베이스 구조를 설계할 수 있도록 도와주는 어노테이션이다."
하나의 데이터 모델 엔터티 내부의 컬럼을 재사용 가능한 클래스 단위로 묶어 관리할 수 있게 해 준다.
별도의 테이블을 생성하지 않으며, 같은 테이블에 필드들을 포함한다.
이해를 돕기 위해 현재 진행중인 알고리즘 대회 사이트 프로젝트의 ERD를 가져와 보았다.
제출(submissions), 문제(problems), 테스트케이스(test_cases) 테이블에서 (생성일자, 수정일자) 컬럼이 반복돼서 사용되는 상황이다.
따라서 createdAt, updatedAt Column을 Embeddable Class로 분리하여 재사용 가능한 구조로 변경해 보고자 한다.
Usage
Embeddable로 만들 클래스에는 @Embeddable Annotation을 적어주고
Embeddable로 만든 클래스를 사용하는 코드에서 @Embedded Annotation을 적어주면 된다.
BaseTimeEntity
createdAt, updatedAt Column을 하나로 묶은 Embeddable Type을 선언해 주었다.
@Embeddable Annotation을 사용해 JPA에 Embeddable Type임을 명시해 준다.
@Embeddable
@Getter
public class BaseTimeEntity {
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
// 기본 생성자 (JPA 필수)
protected BaseTimeEntity() {}
// 생성용 생성자
public BaseTimeEntity(LocalDateTime createdAt, LocalDateTime updatedAt) {
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
@PrePersist
public void prePersist() {
if (this.createdAt == null || this.updatedAt == null) {
LocalDateTime now = LocalDateTime.now();
this.createdAt = now;
this.updatedAt = now;
}
}
@PreUpdate
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
}
Problem Entity
@Entity
@Table(name = "problems")
@Data
@AllArgsConstructor
public class Problem {
...
@Embedded
private BaseTimeEntity timeInfo;
...
}
TestCase Entity
@Entity
@Table(name = "test_cases")
@Data
@AllArgsConstructor
public class TestCase {
...
@Embedded
private BaseTimeEntity timeInfo;
// 기본 생성자
public TestCase() {
this.timeInfo = BaseTimeEntity.now();
}
...
}
Embedded Type 사용 시 주의점
Embedded Type 은 기본적으로 변경 불가능 하도록 설계해야 한다.
@Setter Annotation은 지운 뒤, 생성자에서 값을 모두 초기화하는 방식으로 클래스 구조를 작성하도록 하자.
JPA 기본 스펙상 Entity, Embeddable은 리플렉션, 지연로딩 기술 제공을 위해 Default Constructor를 요구한다.
이때 기본 생성자는 외부에서 호출되지 않는다.
따라서 Public으로 선언해 어디서나 접근 가능하게 허락하기보다는 protected로 선언하여 같은 패키지, 상속 클래스만 접근 가능하도록 코드를 작성하도록 하자.
'🌿 Spring Framework > JPA' 카테고리의 다른 글
[JPA] @Transactional (0) | 2025.09.23 |
---|