1. 복합 값(임베디드) 타입
아래 포스팅의 [3-3)@EmbeddedId 방식]과 사용 방법이 비슷하다. 아래 포스팅에서는 복합 키(@EmbeddedId)를 다룬 것이고, 이번 포스팅에서는 키가 아닌 복합 값(@Embedded)을 다룰 것이다.
https://kimcoder.tistory.com/486
임베디드 타입은 엔티티와 달리 식별자라는 개념이 없다.★
예를 들어, Member 엔티티에 다음과 같은 정보들이 들어있다고 하자.
Member |
id |
name |
city |
street |
zipcode |
여기에서 {city, street, zipcode}는 큰 의미로 주소를 나타낸다. 그래서 {city, street, zipcode}를 하나로 묶어서 임베디드(복합 값) 타입으로 정의하면 Member 엔티티를 더욱 응집력 있게 만들 수 있게 된다.
임베디드 타입도 엔티티의 값이기 때문에 엔티티는 결국 하나의 테이블에 매핑된다는 사실도 알아두자. 즉, MEMBER 테이블에 저 5개의 정보가 모두 매핑된다.
<Member.class>
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
private String name;
@Embedded Address homeAddress;
// ...
}
<Address.class>
@Embeddable
@EqualsAndHashCode
public class Address {
@Column(name="CITY")
private String city
private String street;
private String zipcode;
// ...
}
- 참고로, 임베디드 타입에도 연관관계를 설정할 수 있다. 임베디드 타입에 있는 값을 다시 세밀하게 분리했다면 @Embeddable 클래스의 필드에 다시 @Embedded를 설정하면 된다.
@Embeddable
public class Address {
String street;
String city;
@Embedded Zipcode zipcode; // Zipcode 임베디드 타입을 따로 정의해서 사용할 것
// ...
}
- 드문 경우지만, 한 엔티티에 같은 임베디드 타입을 중복해서 사용하게 되면 컬럼명이 중복된다. 이 때는 @AttributeOverrides 어노테이션을 사용해서 속성을 재정의해서 컬럼명의 중복을 피할 수 있다.
@Embedded Address homeAddress; // 1번째 Address 임베디드 타입
@Embedded
@AttributeOverrides({
@AttributeOverride(name="city", column=@Column(name="COMPANY_CITY")),
@AttributeOverride(name="street", column=@Column(name="COMPANY_STREET")),
@AttributeOverride(name="zipcode", column=@Column(name="COMPANY_ZIPCODE"))
})
Address companyAddress; // 2번째 Address 임베디드 타입
- 임베디드 타입이 null값이면 그 안에 있는 모든 컬럼 값들도 null이 된다.
- 임베디드 타입은 기본적으로 엔티티와 같이 즉시 로딩으로 조회된다.
2. 불변 객체
- 임베디드 타입도 자바에서는 객체 타입이기 때문에, 임베디드 타입을 여러 엔티티에서 공유해서 사용하는 경우에는 속성값을 수정했을 때 공유 참조로 인해 의도하지 않게 다른 엔티티의 속성값까지 바뀌어버린다. 이를 부작용이라고 하며, 이러한 부작용을 막기 위해 객체를 불변하게 만들어서 값을 수정할 수 없게 하면 된다.
- 불변 객체를 구현하는 방법은 여러 가지가 있지만 가장 간단한 방법은 생성자로만 임베디드 타입 객체를 생성하고 수정자를 제거하는 것이다. 만약 값을 수정해야 한다면 다음과 같이 새로운 객체를 생성해서 사용해야 한다.
Address address = member1.getCompanyAddress(); // member1의 주소 정보를 가져온다.
Address newAddress = new Address(address.getCity()); // member1의 주소 정보를 활용하여 새로운 객체를 생성한다.
member2.setCompanyAddress(newAddress); // 새로 생성한 객체를 member2의 주소로 설정한다.
● 참고자료 : 자바 ORM 표준 JPA 프로그래밍
'Spring 사전 준비 > JPA Hibernate' 카테고리의 다른 글
[JPA] JPQL의 작성 (0) | 2022.08.04 |
---|---|
[JPA] 값 타입 컬렉션 (0) | 2022.08.03 |
[JPA] CASCADE 기능 (0) | 2022.08.03 |
[JPA] 즉시 로딩과 지연 로딩 (0) | 2022.08.01 |
[JPA] 프록시 객체 (0) | 2022.08.01 |
댓글