풀스택 강의 중 나온 @Embeddable 과 @Embedded, @AttributeOverride 를 정리해보자!
@Embeddable, @Embedded
Embedded 는 끼워 넣다, 간직하다 라는 뜻을 가지고 있는데, DB 에는 객체를 넣을 수 없기 때문에 이 어노테이션을 사용하면 말 그대로 객체를 DB 에 끼워 넣을 수 있게 해 준다, 는 의미로 받아들이면 된다.
임베디드 타입을 적용하려면 새로운 클래스를 만들고 해당 클래스에 @Embeddable 을 선언해준다. 그리고 임베디드 타입으로 묶으려던 속성들을 넣어준 뒤 각 속성에 @Embedded 어노테이션을 붙여주면 된다.
- @Embeddable : 값 타입을 정의하는 곳에 표시한다.
- @Embedded : 값 타입을 사용하는 곳에 표시한다.
위 사진처럼 사용하게 되면 DB 에 sender 와 receiver, account_number 컬럼이 생성된다.
@AttributeOverride, @AttributeOverrides
하나의 클래스를 통해 여러 개의 정보를 만들고 싶은경우 컬럼명을 재정의해줄 수 있는 어노테이션이다.
@Embeddable
public class Address {
private String city;
private String district;
private String detail;
private String zipCode;
}
예를 들어 위의 코드처럼 회사의 주소와 집 주소의 형태는 시, 구, 상세 주소, 우편번호로 동일하다.
@Entity
@Table(name = "PERSON")
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
@Embedded
private Address homeAddress;
@Embedded
private Address companyAddress;
}
이러한 경우 컬럼명을 재정의 해주지 않고 위 처럼 바로 사용하면 Repeated column in mapping for entity 라는 중복 에러가 발생한다. @Embedded 를 사용하는 경우 객체의 이름이 아닌 해당 객체 안에 작성된 필드의 이름을 컬럼으로 사용하기 때문이다.
재정의는 아래와 같이 해주면 된다.
@Entity
@Table(name = "user")
public class User {
.....
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "home_city")),
@AttributeOverride(name = "district", column = @Column(name = "home_district")),
@AttributeOverride(name = "detail", column = @Column(name = "home_address_detail")),
@AttributeOverride(name = "zipCode", column = @Column(name = "home_zipCode"))
})
private Address homeAddress;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "company_city")),
@AttributeOverride(name = "district", column = @Column(name = "company_district")),
@AttributeOverride(name = "detail", column = @Column(name = "company_address_detail")),
@AttributeOverride(name = "zipCode", column = @Column(name = "company_zipCode"))
})
private Address companyAddress;
.....
}
여기서 의문은, @Column 어노테이션을 사용해서 속성 하나 하나 네이밍을 다시 해주면 안 될까?라는 것인데, 만약 아래처럼 사용해본다고 가정해보자.
@Embeddable
public class Address {
@Column(name = "home_city")
private String city;
@Column(name = "home_district")
private String district;
@Column(name = "home_address_detail")
private String detail;
@Column(name = "home_zipCode")
private String zipCode;
}
이렇게 사용하게 되면 애초에 같은 Address 라는 객체를 사용하는 것이기 때문에 객체 안에 있는 필드의 이름을 컬럼으로 사용하게 되므로 해결 방법이 되지 못한다. 따라서 @AttributeOverride 를 통해 객체 안에서 컬럼을 재정의해야만 한다.
참고 :
Overriding Column Definition With @AttributeOverride with Baeldung
https://www.baeldung.com/jpa-attributeoverride
JPA @Embedded And @Embeddable with Baeldung
https://www.baeldung.com/jpa-embedded-embeddable
[Spring JPA] @Embedded, @Embeddable
임베디드 타입 - 임베디드 타입은 복합 값 타입으로 불리며 새로운 값 타입을 직접 정의해서 사용하는 JPA의 방법을 의미한다.
velog.io
'TIL' 카테고리의 다른 글
인수 테스트 작성하기 (22.11.27 TIL) (0) | 2022.11.27 |
---|---|
SQL - JOIN (22.11.26 TIL) (1) | 2022.11.26 |
SQL 기본 문법 정리해보기 (22.11.24 TIL) (0) | 2022.11.24 |
스프링 @ActiveProfiles (22.11.23 TIL) (0) | 2022.11.23 |
애매한 완벽주의 버리기 (22.11.22 TIL) (0) | 2022.11.22 |
댓글