값 타입은 복잡한 객체 세상을 조금이라도 단순화하려고 만든 개념이다.
임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험하다.
공유하면 발생하는 문제
//그림의 상황을 코드로member1.setHomeAddress(new Address("OldCity"));Address address = member1.getHomeAddress();address.setCity("NewCity"); //회원1의 address 값을 공유해 사용member2.setHomeAddress(address);
회원2에 새로운 주소를 할당하려고 회원1의 주소를 그대로 참조해서 사용했다.
이 코드를 실행하면 회원2의 주소만 “NewCity”로 변경되길 기대하지만 회원1의 주소도 “NewCity”로 변경된다.
그림을 보면 회원1과 회원2가 같은 address 인스턴스를 참조하기 때문이다.
영속성 컨텍스트는 회원1과 회원2 둘 다 city 속성이 변경된 것으로 판단해 회원1, 회원2 각각 UPDATE SQL을 실행한다.
이렇게 뭔가 수정했는데 전혀 예상치 못한 곳에서 문제가 발생하는 것을 부작용(side effect)라고 한다.
부작용을 막기 위해선 값을 복사해서 사용하면 된다.
값 타입의 실제 인스턴스인 값을 공유하는 것은 위험하다.
대신
값(인스턴스)을 복사해서 사용