Member member =newMember();member.setHomeAddress(newAddress("통영","몽돌해수욕장","660-123"));member.getFavoriteFoods().add("짬뽕");member.getFavoriteFoods().add("짜장");member.getFavoriteFoods().add("탕수육");member.getAddressHistory().add(newAddress("서울","강남","660-123"));member.getAddressHistory().add(newAddress("서울","강북","660-123"));em.persist(member);
Member member =em.find(Member.class,1L);Address homeAddress =member.getHomeAddress();Set<String> favoriteFoods =member.getFavoriteFppds();for (String favoriteFood : favoriteFoods) {System.out.println("favoriteFood = "+ favoriteFood );}List<Address> addressHistory =member.getAddressHistory();addressHistory.get(0);
Member member =em.find(Member.class,1L);member.setHomeAddress(newAddress("새로운도시","신도시","123456"));Set<String> favoritFoods =member.getFavoritFoods();favoriteFoods.remove("탕수육");favoriteFoods.add("치킨");List<Address> addressHistory =member.getAddressHistory();addressHistory.remove(newAddress("서울","기존주소","123456"));addressHistory.setHomeAddress(newAddress("새로운도시","신도시","123456"));
값 타입 컬렉션의 제약사항
엔티티는 식별자가 있으므로 엔티티의 값을 변경해도 식별자로 데이터베이스에 저장된 원본 데이터를 쉽게 찾아서 변경할 수있다.
반면에 값 타입은 식별자라는 개념이 없고 단순한 값들의 모음이므로 값을 변경해버리면 데이터베이스에 저장된 원본 데이터를 찾기 어렵다.
값이 변경되면 컬렉션이 남아있는 상황이 많은데 이것을 해결하기 위해서는
값 타입 컬렉션이 매핑된 테이블에 데이터가 많다면 값 타입 컬렉션 대신에 일대다 관계를 고려하기도 한다.
일대다 매핑에 영속성 전이(Cascade) + 고아 객체 제거(ORPHAN REMOVE) 기능을 적용하여 쓸 수도 있다.
값 타입 컬렉션을 사용할 때에 기본 키는 모두 생성키(PK)로 들어가야 한다. (?)
정리
엔티티 타입과 값 타입의 특징은 다음과 같다.
엔티티 타입의 특징
식별자가 있다.
엔티티 타입은 식별자가 있고 식별자로 구별할 수 있다.
생명 주기가 있다.
생성하고, 영속화하고, 소멸하는 생명 주기가 있다.
em.persist(entity)로 영속화 한다.
em.remove(entity)로 제거한다.
공유할 수 있다.
참조 값을 공유할 수 있따. 이것을 공유 참조라 한다.
예를 들어 회원 엔티티가 있다면 다른 엔티티에서 얼마든지 회원 엔티티를 참조 할 수 있다.
값 타입의 특징
식별자가 없다.
생명 주익를 엔티티에 의존한다.
스스로 생명주기를 가지지 않고 엔티티에 의존한다. 의존하는 엔티티를 제거하면 같이 제거된다.
공유하지 않는 것이 안전하다.
엔티티 타입과는 다르게 공유하지 않는 것이 안전하다. 대신에 값을 복사해서 사용해야 한다.