JPA는 크게 2가지 데이터 타입으로 나눌 수 있다.
값 타입은 또 다음과 같이 분류할 수 있다.
[임베디드 타입 예시]
@Embeddable // 임베디드 타입 정의
public class Address {
private String city;
private String street;
private String zipcode;
public Address() {}
...
}
@Entity
public class Member extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MEMBER_ID")
private Long id;
@Column(name="name", nullable = false)
private String username;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private Team team;
// 임베디드 타입 사용
@Embedded
private Address address;
...
}
@Entity
public class Member extends BaseEntity {
...
// 임베디드 타입 사용
@Embedded
private Address homeAddress;
@Embedded
@AttributeOverrrides({
@AttributeOverrride(name="city",
column=@Column("work_city")
@AttributeOverrride(name="street",
column=@Column("work_street")
@AttributeOverrride(name="zipcode",
column=@Column("work_zipcode"))
})
private Address workAddress;
...
}
[값 타입 컬렉션 예시]
@Entity
public class Member {
...
@ElementCollection
@CollectionTable(name="FAVORITE_FOOD", joinColumns =
@JoinColumn(name="member_id"))
@Column(name="food_name")
private Set<String> favoriteFoods = new HashSet<>();
@ElementCollection
@CollectionTable(name="ADDRESS", joinColumns =
@JoinColumn(name="member_id"))
private List<Address> addressHistory = new ArrayList<>();
...
}
[DB 테이블 생성 결과]
직접 작성해보고 생성결과를 봐야 더욱 와닿는 것 같다.
특히 값 타입 수정부분은 나가는 쿼리를 직접 보는 것을 추천한다.
값 타입은 식별자 개념이 없다고 위에서 언급했다.
그래서 값이 변경될 경우 추적이 어려워서 값 타입 컬렉션을 수정할 경우 주인 엔티티와 연관된 모든 데이터를 삭제하고 현재 값 타입 컬렉션에 있는 값들을 모두 다시 저장한다........
참고로 값 타입 컬렉션은 영속성 전이와 고가 객체 제거 기능을 필수로 가진다고 볼 수 있다.
그리고 지연 로딩 전략을 사용한다.
값 타입 컬렉션을 사용할 때 매우매우 생각을 많이 해보고 ,,, 꼭 사용해야하는지 고민하자. 일대다 관계로 풀어낼 수 있으면 일대다 관계로 풀어내자
자바 ORM 표준 JPA 프로그래밍-기본편을 학습하면서 정리한 블로그입니다.