값 타입 공유 참조
- 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험함
- 부작용 발생
예제
Main.java
Address address = new Address("city", "street", "10000");
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(address);
em.persist(member);
Member member2 = new Member();
member2.setUsername("member1");
member2.setHomeAddress(address);
em.persist(member2);
member.getHomeAddress().setCity("newCity");
tx.commit();
- member의 city 를 newCity 로 변경했는데 member2도 같이 변경되는 오류 발생함!!
실행 결과
- 값 타입의 실제 인스턴스인 값을 공유하는 것은 위험
- 대신 값(인스턴스)를 복사해서 사용
예시
Main.java
Address address = new Address("city", "street", "10000");
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(address);
em.persist(member);
Address copyAddress = new Address(address.getCity(), address.getStreet(), address.getZipcode());
Member member2 = new Member();
member2.setUsername("member1");
member2.setHomeAddress(copyAddress);
em.persist(member2);
member.getHomeAddress().setCity("newCity");
tx.commit();
실행결과
객체 타입의 한계
- 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다.
- 문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
- 자바 기본 타입에 값을 대입하면 값을 복사한다.
- 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.
- 객체의 공유 참조는 피할 수 없다.
불변 객체
- 객체 타입을 수정할 수 없게 만들면 부작용을 원천 차단
- 값 타입은 불변 객체로 설계해야함
- 불변 객체 : 생성 시점 이후 절대 값을 변경할 수 없는 객체
- 생성자로만 값을 설정하고 수정자(Setter) 를 만들지 않으면 됨
- 참고 : Integer, String 은 자바가 제공하는 대표적인 불변 객체
예시
Address.java
@Embeddable
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
public Address() {
}
}
변경 하려 하면 오류가 난다.
근데 setter 를 다 없애버려서 member만 있을 경우에도 변경이 안되는 문제가 발생한다.
만약 값을 변경하고 싶은 경우에는 어쩔 수 없이 새로운 객체를 다시 생성해서 넣어줘야된다.
예제
Main.java
Address address = new Address("city", "street", "10000");
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(address);
em.persist(member);
Address newAddress = new Address("NewCity", address.getStreet(), address.getZipcode());
member.setHomeAddress(newAddress);
tx.commit();
'Spring > Spring JPA' 카테고리의 다른 글
값 타입 컬렉션 (0) | 2024.03.29 |
---|---|
값 타입의 비교 (0) | 2024.03.29 |
임베디드 타입 (0) | 2024.03.22 |
값 타입 (0) | 2024.03.22 |
실습 5 - 연관관계 관리 (0) | 2024.03.20 |