JPA의 어노테이션중에 @Embedded 어노테이션에 대해 알아보겠습니다.
다음과 같은 테이블이 존재한다고 가정해보겠습니다.
create table hotel
(
id int not null,
addr1 varchar(255),
addr2 varchar(255),
zip_code varchar(255),
)
DB 상에서는 모두 한개의 테이블에 속해 있지만, 스프링에서 주소 부분만 정규화하고 싶을 때, 또는 여러 테이블에 공통적으로 가지고 있는 컬럼들을 따로 추출해서 하나의 class로 관리하고 싶을 때 @Embedded 어노테이션을 사용하면 좋습니다.
위 코드의 hotel 테이블을 Spring의 엔티티 객체로 정의를 하면 다음과 같습니다.
@Entity
@Table(name="hotel")
public class Hotel {
@Id
private int id;
private String addr1;
private String addr2;
@Columnt(name="zip_code")
private String zipCode;
}
여기서 이제 주소를 나타내는 addr1, addr2 그리고 zipCode를 따로 Address이라는 클래스로 정의하고 싶어졌습니다.
public class Address {
private String addr1;
private String addr2;
private String zipCode;
}
이제 여기에 @Embedded 어노테이션을 적용해보겠습니다. 일단 따로 추출한 클래스에 @Embeddable 어노테이션을 추가해줍니다.
@Embeddable
public class Address {
private String addr1;
private String addr2;
@Column(name="zip_code")
private String zipCode;
}
이렇게 하면 준비는 끝입니다. 컬럼이름과 프로퍼티 이름이 일치하지 않을때는 @Column어노테이션을 이용해서 매칭 시켜주변 됩니다.
이제 다시 Hotel 클래스로 돌아와서 다음과 수정합니다.
@Entity
@Table(name="hotel")
public class Hotel {
@Id
private int id;
@Embedded
private Address address;
}
@Embbedable 어노테이션을 추가한 클래스를 추가하고 @Embedded 어노테이션을 추가하면 모든 설정은 끝입니다. 이제는 address.addr1으로 접근할수 있으며 객체화 했기 때문에 다른 엔티티에도 사용할수 있어 재사용성도 높아졌습니다.
하지만 다른 문제도 있습니다.
만약에 hotel테이블에 Address와 형식은 같지만 이름만 다른 컬럼들이 추가되면 어떻게 해야할까요?
@Entity
@Table(name="hotel")
public class Hotel {
@Id
private int id;
@Embedded
private Address address;
@Embedded
private Address workAddress;
}
위와 같이 hotel 엔티티에 Address 타입인 wordAddress을 추가하고 DB에는 work_address1 , work_address2 , work_zip_code 컬럼이 추가 됬다고 가정하고 실행해보면...

이와 같은 에러를 마주하게 됩니다. Address가 중복되었다는 오류를 내보내고 있죠. 이를 해결하기 위해 @AttributeOverride 어노테이션을 사용합니다.
@ArrtributeOverride 어노테이션은 같은 타입의 @Embedded 필드가 2개 이상 존재하여 오류를 발생할때 쓸수 있는 어노테이션입니다.
@Entity
@Table(name="hotel")
public class Hotel {
@Id
private int id;
@Embedded
private Address address;
@AttributeOverrdides({
@AttributeOverrid(name="addr1", column=@Column(name="work_addr1")),
@AttributeOverrid(name="addr2", column=@Column(name="work_addr2")),
@AttributeOverrid(name="zip_code", column=@Column(name="work_zip_code")),
})
@Embedded
private Address workAddress;
}
@AttributesOverrides 어노테이션을 오버라이드하고자 하는 Embedded 필드에 추가해줍니다. 그리고 @AttributesOverride 어노테이션을 통해 매칭되는 컬럼명을 변경할수 있습니다. name에는 변경하고자하는 컬럼명을, column에는 변경하고자 하는 컬럼명을 입력하면 됩니다.
이렇게 설정하면 변경된 컬럼명을 자동으로 매칭해주고 오류가 발생하지 않게 됩니다.
JPA 엔티티를 정의 하다 보면 중복되는 필드들이 있어도 한줄 한줄 하드코딩을 했었는데, Embedded을 알게 되니까 앞으로 자주 사용하게 될것 같습니다. JPA가 마냥 불편하다고만 생각했는데 이렇게 하나둘 기능을 알아가니까 JPA를 선호하는 이유를 알아 가는 것같습니다.