[JPA] @Embedded, @Embeddable

2024. 7. 16. 23:57·Spring/JPA

DDD를 공부하다가 한 엔티티에 여러 객체들을 사용할 일이 많아져서 방법을 찾다가 @Embedded, @Embeddable 을 사용해야 한다는 것을 봤다.

 

 

이게 뭔지, 어떨 때 사용하는지 알아보자! 😎


 

주문 엔티티가 다음과 같다.

(참고로 도메인 주도 개발 중이기 때문에 엔티티 코드가 좀 더러워요..)

@Entity
@NoArgsConstructor
public class Order {

    @EmbeddedId
    private OrderId id;

    private OrderState orderState;

    @Embedded
    private Orderer orderer;

    @ElementCollection(fetch = FetchType.LAZY)
    private List<OrderLine> orderLines;

    @Embedded
    private ShippingInfo shippingInfo;

    @Convert(converter = MoneyConverter.class)
    private Money totalAmounts;

    public Order(OrderId id, Orderer orderer, List<OrderLine> orderLines,
                 ShippingInfo shippingInfo, OrderState orderState) {
        setId(id);
        setOrderer(orderer);
        setOrderLines(orderLines);
        setShippingInfo(shippingInfo);
        this.orderState = orderState;
    }
    
    // 주요 메서드, ...
    
}

 

위의 코드를 보다시피 주문 엔티티에는 아래의 항목이 있다.

  • 주문 고유 번호 : OrderId
  • 주문 상태 : OrderState
  • 주문자 : Orderer
  • 주문 제품 : List<OrderLine>
  • 배송지 정보 : ShippingInfo

 

 

(참고) 객체를 묶어서 사용하는 이유?

 

보통 배송지 정보를 주문 엔티티에서 사용할 땐, 위의 코드와 같은 컬럼 형태로 코드를 작성하면

@Entity
@NoArgsConstructor
public class Order {

    ...
    
    // 배송지 주소
    private String postalCode; // 우편번호
    private String state;      // 시/도
    private String city;       // 시/군/구
    private String district;   // 읍/면/동
    private String streetAddress; // 상세주소
    
    // 받는 사람
    private String name;
    private String phone;
    
    // 주문 특이사항
    private String message;
    
    ...
    
}

 

이런 식으로 하나하나 풀어서 나열하게 된다.

 

그런데 위의 방식은 가독성이 너무 떨어진다.

 

이러한 이유 때문에 객체로 각각 묶어서 사용하면 가독성을 높일 수 있다.

 

이럴 때 사용하는 것이 @Embedded, @Embeddable 이다.

 

 

 

@Embedded

  • 임베디드 타입을 사용하기 위한 Entity에서 사용
  • 데이터베이스 테이블의 한 열이 아닌 여러 열에 매핑되는 복합 값 타입을 나타냄

@Embeddable

  • 임베디드 타입으로 사용하기 위해 생성한 Class에서 사용

 

 

그리고 단순한 컬럼 타입 말고 @EmbeddedId를 사용한다면 ID 컬럼도 충분히 객체로 사용할 수 있다.

 

 

그 대신 객체를 엔티티의 ID 컬럼 즉, 식별자로 사용한다면 이 컬럼을 복합키로 인식하게 된다.

 

@Entity
@NoArgsConstructor
public class Order {

    @EmbeddedId
    private OrderId id;
    
    ...
		
}

 

@Getter
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
public class OrderId implements Serializable {
    private String id;
    
    // 복합키일 경우 이 곳에 더 많은 컬럼이 들어올 수 있음
    
}

 

또한, 엔티티의 ID가 되는 객체는 반드시 Serializable 을 상속받아야 한다.

 

 

그 이유는 JPA가 엔티티를 식별할 때 이 복합 키를 직렬화 가능하게 만들어야 하기 때문이다.

 

 

영속성 컨텍스트는 엔티티의 PK 즉, 위의 OrderId와 같은 식별자를 사용해 엔티티를 관리한다.

 

 

그런데 이 영속성 컨텍스트에서 관리되는 모든 엔티티는 Serializable 을 구현해야 한다.

→ 무조건 Serializable 을 구현해야 하는 건 아니지만, JPA 표준 스펙은 엔티티에 Serializable 을 구현하도록 권장한다.

 


참고

 

https://www.inflearn.com/questions/16570/버그-문의드려봅니다

 

버그 문의드려봅니다. - 인프런

영한님 안녕하세요. 강좌들으면서 실무에서 직접 해보고 있는데 풀리지 않는 오류가 하나 등장했습니다. ManyToOne 단방향 맵핑한 영역이 있습니다. (MemberWebUser / MemberCompany) (다만, PK 가 아닌 Unique

www.inflearn.com

 

https://product.kyobobook.co.kr/detail/S000001810495

 

도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지 | 최범균 - 교보문고

도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지 | 가장 쉽게 배우는 도메인 주도 설계 입문서!이 책은 도메인 주도 설계(DDD)를 처음 배우는 개발자를 위한 책이다. 실제 업무에 DDD를

product.kyobobook.co.kr

 

 

'Spring > JPA' 카테고리의 다른 글

[JPA] Spring JPA 페이징 성능 향상  (2) 2024.12.24
[JPA] 여러 트랜잭션이 하나의 영속성 컨텍스트?  (0) 2024.07.31
'Spring/JPA' 카테고리의 다른 글
  • [JPA] Spring JPA 페이징 성능 향상
  • [JPA] 여러 트랜잭션이 하나의 영속성 컨텍스트?
오도형석
오도형석
  • 오도형석
    형석이의 성장일기
    오도형석
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • MSA 모니터링 서비스
        • DB
      • 스파르타 코딩클럽
        • SQL
        • Spring
      • 백엔드
        • Internet
        • Java
        • DB
      • 캡스톤
        • Django
        • 자연어처리
      • Spring
        • JPA
        • MSA
      • ETC
        • ERROR
      • 개발 일기 N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 인기 글

  • 태그

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
오도형석
[JPA] @Embedded, @Embeddable
상단으로

티스토리툴바