본문 바로가기
JPA

[JPA] 임베디드 타입(복합 값 타입)

by byeongoo 2020. 4. 26.

1. 임베디드 타입

  • 새로운 값 타입을 직접 정의할 수 있음 
  • JPA는 임베디드 타입(embedded type)이라 함 
  • 주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 함 
  • int, String과 같은 값 타입

예를들어서 회원 엔티티는 이름과 근무 시작일, 근무 종료일, 주소 도시, 주소 번지, 주소 우편번호를 갖는다고 하겠습니다. 여기서 임베디드 타입을 사용한다면 주소와 관련된 속성들을 임베디드 타입에 모아줄 수 있습니다. 이렇게 한다면 활용성이 높아지겠죠.

임베디드 타입을 이용해서 회사에서 일한 기간을 나타내는 Period와 Address 임베디드 타입을 만들면 다음과 같습니다.

2. 임베디드 타입 사용법

  • @Embeddable: 값 타입을 정의하는 곳에 표시
  • @Embedded: 값 타입을 사용하는 곳에 표시
  • 기본 생성자 필수

임베디드 타입도 값 타입입니다. 엔티티가 생성되고 소멸할 때 같이 죽습니다.

3. 임베디드 타입의 장점

  • 재사용
  • 높은 응집도
  • Period.isWork()처럼 해당 값 타입만 사용하는 의미 있는 메소 드를 만들 수 있음
  • 임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티 티에 생명주기를 의존

데이터 베이스 입장에서는 회원테이블은 똑같습니다. 대신 매핑만 해줍니다. 객체는 데이터뿐만 아니라 메소드라는 기능을 가지고 있기 때문에 이렇게 묶였을 때 갖을 수 있는 이득이 있습니다. 객체와 테이블을 아주 세밀하게 매핑하는 것이 가능해집니다. 또한 설계적으로 봤을 때도 모델링이 깔끔하게 떨어집니다. 회원은 이름, 주소, 일한 기간을 갖는다고 말하면 됩니다.

 

  • 임베디드 타입은 엔티티의 값일 뿐이다.
  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
  • 객체와 테이블을 아주 세하게(find-grained) 매핑하는 것이 가 능
  • 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래 스의 수가 더 많음

4. 임베디드 타입과 연관관계

JPA 표준스펙에 있는 내용입니다. Address는 또 임베디드 타입을 갖을 수 있습니다. 재밌는 사실은 PhoneNumber라는 임베디드 타입은 PhoneEntity를 갖을 수 있습니다.

@Embeddable
public class Address{

    private String city;
    private String street;
    private String zipcode;
    
    private Member member;
    
    public Address(){}
    
    public Address(String city, String street, String zipcode){
    	this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }

}

이렇게도 가능합니다.

@Embeddable
public class Address{

	private String city;
    private String street;
    
    @Column(name = "ZIPCODE")
    private String zipcode;
    
    public Address(){}
    
    public Address(String city, String street, String zipcode){
    	this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }

}

5. 속성 재정의 : @AttributeOverride

  • 한 엔티티에서 같은 값 타입을 사용하면?
  • 컬럼 명이 중복됨
  • @AttributeOverrides, @AttributeOverride를 사용해서 컬러 명 속성을 재정의

한 Entity에서 Address 타입이 2개이면 에러가 납니다. 이때 사용하는게 @AttributeOverrides 입니다. 잘 사용하진 않습니다.

@Embedded
private Address homeAddress;

@Embedded
private Address workAddress;

위의 코드를 아래처럼 바꾸면 됩니다.

@Embedded
private Address homeAddress;

@Embedded
@AttrivuteOverrides({
	@AttributeOverride(name="city",
        column=@Column(name="WORK_CITY")),
    @AttributeOverride(name="street", 
        column=@Column(name="WORK_STREET")),
    @AttributeOverride(name="zipcode",
        column=@Column(name="WORK_ZIPCODE"))
})
private Address workAddress;

이렇게 만들 경우 테이블에 따로 컬럼이 생성되는 것을 확인할 수 있습니다.

한개라면 @AttributeOverride를 사용하면 됩니다.

 

또한 임베디드 타입의 값이 null이면 매핑한 컬럼 값은 모두 null입니다.

REFERENCE

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

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 서버 데이터베이스 프레임워크 및 라이브러리 프로그래밍 언어 서비스 개발 Java JPA Spring Data JPA 온라인 강의 ORM, JPA, 자바, java, 우아한형제들

www.inflearn.com

 

'JPA' 카테고리의 다른 글

[JPA] 값 타입 컬렉션  (0) 2020.04.26
[JPA] 값타입과 불변 객체  (0) 2020.04.26
[JPA] 고아객체  (0) 2020.04.22
[JPA] 영속성전이(CASCADE)와 고아 객체  (0) 2020.04.22
[JPA] 즉시로딩과 지연로딩  (0) 2020.04.22