인프런 커뮤니티 질문&답변

니야옹님의 프로필 이미지
니야옹

작성한 질문수

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

값 타입 컬렉션 삭제부분에서 이해가 안가는곳이 있는데요

작성

·

332

·

수정됨

0

  • 챕터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 쿼리를 실행한 것입니다.

이해에 도움이 되셨길 바랍니다. 추가적인 질문이나 궁금한 점이 있으면 언제든지 물어보세요!

니야옹님의 프로필 이미지
니야옹

작성한 질문수

질문하기