inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

자바 ORM 표준 JPA 프로그래밍 - 기본편

값타입과 엔티티 차이 고민

279

창신동 장첸

작성한 질문수 115

0

강의 39분10초에 "엔티티는 값을 마음껏 수정할 수 있다" 는 말씀에 이해를 못하고 있습니다.

아래에는 제가 정리한 값타입의 특징과, 한 예시에 대해서 값타입/엔티티를 적용했을 때 상황을 고려해봤습니다.

마지막에 내린 결론이 올바른지 궁금합니다.

[값 타입의 특징]

- 서로 다른 두 엔티티 Member A, B는 한 값타입객체를 공유하지 말 것

- 엔티티의 필드로서 값타입(Address)에 대하여 값타입의 필드(city)를 수정하고 싶을 땐, new Address(..)로 새로운 객체를 사용할 것

혹여나 공유하는 실수를 했을 때 컴파일러로 찾아내기 어렵다. 따라서 대응책으로 setter메소드 없는 불변객체로 설계한다.

(예시) 서로 다른 회원 A, B가 한 가족이라 같은 주소에 살고있다. 그런데 A가 독립해서 주소를 옮겼다.

1.값타입 경우)

- 두 회원이 동일한 Address 값타입의 인스턴스를 공유하지 않고 각 회원별로 Address인스턴스가 달라야함.

- 따라서, memberA.getAddress( ).setCity('xxx') 로 직접 수정해도 B의 address인스턴스에 부작용 없지만,

   코딩을 할 때 실수로 동일 Address객체를 공유하도록 코드를 작성 할 수 있기에, 이를 방지하기 위해 값타입에 setter메소드정      의 안함

- 즉, setCity( )메소드를 못 쓰니까 도시속성을 바꿀 수가 없음. 따라서 memberA.setAddres(new Address( ~~) )로 새 객체를  만들어 교체해줌

2.엔티티 경우)

- 엔티티의 본래 특성상 parent엔티티 A, B가 같은 child엔티티C를 공유가능함(예. 동아리A, B는 같은 학생C를 회원으로 받을 수 있음) 

- 그러나 위 (예시)의 비즈니스 특성상 엔티티도 공유하면 안됨(한 명이 이사한 주소로 다른 한 명도 주소가 변경되는 문제)

- 엔티티 또한 아래 코드와 같이 공유하게 되면 addEntity.setCity('성남', '분당구') 로 A, B모두 주소가 변경됨

AddressEntity addrEntity = new AddressEntity('서울', '강남구');
memberA.setAddressEntity( addrEntity );
memberB.setAddressEntity( addrEntity );
 
memberA.getAddress().setCity('성남', '분당구');

- 따라서, 엔티티의 경우도 setCity와 같은 setter메소드가 있으나 회원A의 address를 얻어와  개발자 마음껏 setter수정을 할 수 없을것 같다 !?

강의의 39분10초 설명 "엔티티는 값을 마음껏 수정할 수 있다"에 반하는 결론이라 어디가 틀렸는지 짚어주셨으면 좋겠습니다.

감사합니다.

JPA java

답변 1

0

김영한

안녕하세요. ddoddo님

엔티티는 값을 마음껏 수정할 수 있습니다.

따라서 비즈니스 특성상 제약이 있다면 이 부분은 그렇게 안되도록 코드로 막아야 합니다.

반면에 값 타입은 값을 수정할 수 없도록 설계했기 때문에 이런 문제가 원천 발생하지 않습니다.

감사합니다.

0

창신동 장첸

선생님, 강의에서와 답변내용으로 '값객체와 달리 엔티티는 수정가능한 이유'에 대해 언급이 없으셔서 다시 한 번 질문드려도 될까요..?

아래는 수정가능한 이유에 대해 좀 더 고민을 해본 내용입니다.

단순히 엔티티에 setter메소드를  정의할 수 있어서 엔티티가 수정가능하다는 것과 별개로 다른 이유는 없을까?

값객체의 경우 setter메소드를 막아 수정불가능하게 만듬. 그 이유는 값객체가 개발실수로 공유되는 코드로 작성될 경우를 대비하기 위함.  (동일한 값객체를 공유하는)두 부모 엔티티에 동시에 영향주는 것을 주의해야함.

그러나, 일대다 연관관계로 설계를 하면 위와같은 문제가 발생할 일이 없음.

일대다 연관관계의 설계가  서로 다른 두 회원(일 쪽)이 동일한 주소엔티티(다 쪽)를 공유하는 것은 불가함을 보장해주기 때문에 주소엔티티를 member.getAddressList( ).get(0) 으로 얻어와 직접 setXXX('ooo')로 수정을 하는 것이 가능하다....

0

김영한

안녕하세요. ddoddo님

Q: 그러나, 일대다 연관관계로 설계를 하면 위와같은 문제가 발생할 일이 없음.

-> 지금은 문제가 없어 보이지만 다른곳에서 주소 엔티티를 참조하도록 설계가 추가 된다면 문제가 발생할 수 있습니다. 예를 들어서 team -> addressList를 참조할 수 있도록 설계가 추가되는 것이지요.

반면에 값 타입은 team -> address(값타입)로 참조가 향후 추가되어도 사이드 이펙트가 발생하지 않습니다.

여기서 핵심은 일대다, 다대일 같은 조건이 아닙니다.

참조를 통한 사이트 이펙트가 발생하는가 하지 않는가 입니다. 그리고 지금 뿐만 아니라 요건이 추가되었을 때도 함께 고려해야합니다.

감사합니다.

0

창신동 장첸

긴 질문글을 올리게 돼 죄송합니다.

그리고 명확한 설명에 감사드립니다.

이제야 이해가 됐습니다...ㅠㅠ

0

김영한

이해가 되셨다니 다행입니다^^

벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?

0

33

2

inheritance startegy 선택시 고려사항

0

24

1

Entity 동등성 비교

0

23

1

실무 조언 관련 질문입니다.

0

48

1

H2데이터베이스 파일 생성

0

58

2

서브쿼리 강의에서 ALL 예시 관련 질문드립니다.

0

57

2

수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?

0

58

1

JPQL 메소드와 락

0

55

1

Delivery @OneToOne

0

61

1

17강 4~5분대 테이블 값 조회가 안됩니다.

0

97

2

UnsupportedOperationException 발생

0

86

3

H2 Database 연결이 안됩니다.

0

98

2

연관관계 매핑 질문드립니다.

0

88

2

h2데이터베이스 실행오류

0

110

2

persistence.xml

0

112

2

양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?

0

83

1

영속성 컨텍스트

0

69

1

JPA 프록시

0

98

1

Native Query와 MyBatis

0

71

1

영속성 컨텍스트는 어떤 메모리에 저장되는건가요?

0

92

1

임베디드 타입 예시 코드 관련 질문

0

121

3

명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요

0

96

3

인텔리제이 패키지 커서 단축키 질문

0

109

2

혹시 현재는 ID 데이터 타입이 String이면 안되나요?

0

149

1