값 타입 컬렉션 삭제부분에서 이해가 안가는곳이 있는데요
396
작성한 질문수 7
챕터9 값 타입 컬렉션 25분
Address 값 타입 컬렉션 삭제 부분입니다.
우선 삭제되는 부분만 확인하고 싶어서, 새로운 값을 추가하지는 않았습니다.
System.out.println("========== 값 타입 컬렉션 주소 삭제================");
findMember.getAddressHistory().remove(new Address("old1", "street", "zipcode"));


데이터는 정상적으로 삭제되었는데, 저는 왜 Member테이블에 대해 update쿼리가 나가는지가 이해가 안가는데요,
Member 테이블에서는 수정사항이 발생할게 없는데 왜 update쿼리도 발생했는지 알 수 있을까요?
혹시 몰라 코드 전체와 결과 남깁니다.
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(new Address("homeCity","street","zipcode"));
member.getFavoriteFoods().add("꾸부라꼬");
member.getFavoriteFoods().add("카페라떼");
member.getFavoriteFoods().add("회");
member.getAddressHistory().add(new Address("old1", "street", "zipcode"));
member.getAddressHistory().add(new Address("old2", "street", "zipcode"));
em.persist(member);
em.flush();
em.clear();
System.out.println("================== 조회 시작 ==================");
Member findMember = em.find(Member.class, member.getId());
System.out.println("================== 컬렉션은 지연로딩, Addr 조회 ==================");
List<Address> addressHistory = findMember.getAddressHistory();
for(Address address : addressHistory) {
System.out.println("address = " + address.getCity());
}
System.out.println("================== 컬렉션은 지연로딩, favorite food 조회 ==================");
Set<String> favoriteFoods = findMember.getFavoriteFoods();
for(String favoriteFood : favoriteFoods) {
System.out.println("favoriteFood = " + favoriteFood);
}
Address homeAddress = findMember.getHomeAddress();
findMember.setHomeAddress(new Address("new change city", homeAddress.getStreet(), homeAddress.getZipcode()));
findMember.getFavoriteFoods().remove("꾸부라꼬");
findMember.getFavoriteFoods().add("무화과 크림치즈 베이글");
System.out.println("========== 값 타입 컬렉션 주소 삭제================");
findMember.getAddressHistory().remove(new Address("old1", "street", "zipcode"));
tx.commit();
Hibernate:
/* insert hellojpa.Member
*/ insert
into
Member
(city, street, zipcode, USERNAME, MEMBER_ID)
values
(?, ?, ?, ?, ?)
Hibernate:
/* insert collection
row hellojpa.Member.addressHistory */ insert
into
ADDRESS
(MEMBER_ID, city, street, zipcode)
values
(?, ?, ?, ?)
Hibernate:
/* insert collection
row hellojpa.Member.addressHistory */ insert
into
ADDRESS
(MEMBER_ID, city, street, zipcode)
values
(?, ?, ?, ?)
Hibernate:
/* insert collection
row hellojpa.Member.favoriteFoods */ insert
into
FAVORITE_FOOD
(MEMBER_ID, FOOD_NAME)
values
(?, ?)
Hibernate:
/* insert collection
row hellojpa.Member.favoriteFoods */ insert
into
FAVORITE_FOOD
(MEMBER_ID, FOOD_NAME)
values
(?, ?)
Hibernate:
/* insert collection
row hellojpa.Member.favoriteFoods */ insert
into
FAVORITE_FOOD
(MEMBER_ID, FOOD_NAME)
values
(?, ?)
================== 조회 시작 ==================
Hibernate:
select
member0_.MEMBER_ID as member_i1_6_0_,
member0_.city as city2_6_0_,
member0_.street as street3_6_0_,
member0_.zipcode as zipcode4_6_0_,
member0_.USERNAME as username5_6_0_
from
Member member0_
where
member0_.MEMBER_ID=?
================== 컬렉션은 지연로딩, Addr 조회 ==================
Hibernate:
select
addresshis0_.MEMBER_ID as member_i1_0_0_,
addresshis0_.city as city2_0_0_,
addresshis0_.street as street3_0_0_,
addresshis0_.zipcode as zipcode4_0_0_
from
ADDRESS addresshis0_
where
addresshis0_.MEMBER_ID=?
address = old1
address = old2
================== 컬렉션은 지연로딩, favoritfood 조회 조회 ==================
Hibernate:
select
favoritefo0_.MEMBER_ID as member_i1_4_0_,
favoritefo0_.FOOD_NAME as food_nam2_4_0_
from
FAVORITE_FOOD favoritefo0_
where
favoritefo0_.MEMBER_ID=?
foavortefood = 꾸부라꼬
foavortefood = 회
foavortefood = 카페라떼
========== 값 타입 컬렉션 주소 삭제================
Hibernate:
/* update
hellojpa.Member */ update
Member
set
city=?,
street=?,
zipcode=?,
USERNAME=?
where
MEMBER_ID=?
Hibernate:
/* delete collection hellojpa.Member.addressHistory */ delete
from
ADDRESS
where
MEMBER_ID=?
Hibernate:
/* insert collection
row hellojpa.Member.addressHistory */ insert
into
ADDRESS
(MEMBER_ID, city, street, zipcode)
values
(?, ?, ?, ?)
Hibernate:
/* delete collection row hellojpa.Member.favoriteFoods */ delete
from
FAVORITE_FOOD
where
MEMBER_ID=?
and FOOD_NAME=?
Hibernate:
/* insert collection
row hellojpa.Member.favoriteFoods */ insert
into
FAVORITE_FOOD
(MEMBER_ID, FOOD_NAME)
values
(?, ?)
Process finished with exit code 0
답변 1
0
안녕하세요, 인프런 AI 인턴이에요. 값 타입 컬렉션에서의 삭제 부분에 대한 질문이시군요.
먼저, 값 타입 컬렉션을 수정하면 JPA는 내부적으로 해당 컬렉션을 삭제하고 다시 추가하는 작업을 수행합니다. 그래서 update 쿼리가 발생하는 것입니다. 이런 작업은 값 타입 컬렉션을 변경할 때마다 수행됩니다.
따라서, 코드에서 findMember.getAddressHistory().remove(new Address("old1", "street", "zipcode"));와 같이 값을 삭제하면, 해당 값이 실제로 삭제되고, 컬렉션을 다시 탐색하여 변경된 컬렉션을 감지하고 JPA에서 이를 업데이트하는 작업이 수행됩니다. 그래서 update 쿼리가 발생한 것입니다.
결과적으로 Member 테이블에서는 수정사항이 발생하지 않았지만, 값 타입 컬렉션인 AddressHistory 컬렉션에서의 변경 사항을 JPA가 인식하여 update 쿼리를 실행한 것입니다.
이해에 도움이 되셨길 바랍니다. 추가적인 질문이나 궁금한 점이 있으면 언제든지 물어보세요!
벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?
0
22
2
inheritance startegy 선택시 고려사항
0
22
1
Entity 동등성 비교
0
18
1
실무 조언 관련 질문입니다.
0
46
1
H2데이터베이스 파일 생성
0
56
2
서브쿼리 강의에서 ALL 예시 관련 질문드립니다.
0
52
2
수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?
0
51
1
JPQL 메소드와 락
0
55
1
Delivery @OneToOne
0
60
1
17강 4~5분대 테이블 값 조회가 안됩니다.
0
93
2
UnsupportedOperationException 발생
0
86
3
H2 Database 연결이 안됩니다.
0
92
2
연관관계 매핑 질문드립니다.
0
85
2
h2데이터베이스 실행오류
0
107
2
persistence.xml
0
106
2
양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?
0
80
1
영속성 컨텍스트
0
65
1
JPA 프록시
0
94
1
Native Query와 MyBatis
0
68
1
영속성 컨텍스트는 어떤 메모리에 저장되는건가요?
0
85
1
임베디드 타입 예시 코드 관련 질문
0
114
3
명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요
0
94
3
인텔리제이 패키지 커서 단축키 질문
0
108
2
혹시 현재는 ID 데이터 타입이 String이면 안되나요?
0
143
1





