- JPA의 임베디드 타입의 경우 기본적으로 객체 타입과 같아 공유 참조에 따른 사이드 이펙트가 발생할 수 있다.
- 이러한 객체의 공유 참조는 막을 수가 없기 때문에 불변하게 설계하고자 한다면 새로 생성하는 방법밖에 없다.
- 공유 참조를 막기 위한 방법 : 생성자를 통한 초기화만 가능하도록 하고 접근자만 노출, 수정자는 노출시키지 않도록 한다.
📚 값 타입의 비교 - 동등성과 동일성 비교 측면
- 기본적으로 인스턴스는 메모리의 어딘가에 위치하게 된다.
- 동일성 측면에서 비교를 하게 되면 같은 값을 가지는 인스턴스라 할지라도 참조 주소가 다르기 때문에 기본적으로 false가 나오게 된다.
- 또한 동등성 측면에서의 경우에도
equals()
메서드는 기본적으로 ==
비교를 하기 때문에 역시 false가 나오게 된다.
- 따라서 값 타입의 경우에는 동일성과 동등성 측면에서 비교를 해줘야 하기 때문에
equals()
메서드와 hashCode()
메서드를 재정의해줘야 한다.
private Set<String> favoriteFoods = new HashSet<>();
private List<Address> addressHistory = new ArrayList<>();
- 엔티티는 식별자가 존재하나 값 타입은 식별자가 존재하지 않는다.
- 값이 변경되면 데이터베이스에 있는 원본 값을 찾기가 어렵다.
- 값 타입 컬렉션에 변경 사항이 발생하면 주인 엔티티와 연관된 모든 엔티티를 삭제하고 값 타입 컬렉션에 있는 값을 모두 다시 저장한다.
- 값 타입 컬렉션을 구성하는 매핑하는 테이블은 구성된 컬럼을 모두 묶어 기본 키를 구성해야 한다. 기본 키로 구성하게 되면 null을 입력할 수 없게 되고 중복된 값도 저장할 수 없게 된다.