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

genesis님의 프로필 이미지

작성한 질문수

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

값 타입 컬렉션

값타입 컬렉션을 엔티티로 변경 후에...

작성

·

1.2K

0

기초 적인 것인데도 해결이 안되서 결국 질문 드립니다.

 

강의 40분 정도 에서 Address 값 타입 컬렉션을 Entity 로 해서 OneToMany로 연관관계 매핑을 하셨습니다.

이렇게 하신 이유가 값타입은 식별자가 없기 때문에, 컬렉션의

값이 변경될 때, update 쿼리가 나가는 것이 아니라, 전체 delete 쿼리 이후에 여러건의 insert 쿼리가 발생되기 때문이라는 것은 이해 했습니다.

그런데, entity로 바꾸신 후에 값을 변경하는 것과 그렇게 변경한 후에 쿼리가 나가는 것은 안보여 주셔서 직접 확인해보려고 하는데 ...... 결과를 확인 할 수가 없네요...ㅠㅠ

 

값을 변경하는 방법을 코딩으로 보여주셨으면 합니다.

 당연히 알고 있는 부분도 어려운 초보입니다.

감사합니다.

답변 4

0

genesis님의 프로필 이미지
genesis
질문자

로그가 첨부가 안되서 여기에 첨부합니다.

 

17:24:03.204 [main] DEBUG org.hibernate.SQL - 

    /* insert collection

        row jpabasic.hellojpa.Member.favoriteFoods */ insert 

        into

            FAVORITE_FOOD

            (MEMBER_ID, FOOD_NAME) 

        values

            (?, ?)

17:24:03.204 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister - Done inserting collection: 3 rows inserted

===============START====================

17:24:03.207 [main] DEBUG org.hibernate.SQL - 

    select

        member0_.MEMBER_ID as member_i1_5_0_,

        member0_.city as city2_5_0_,

        member0_.street as street3_5_0_,

        member0_.zipcode as zipcode4_5_0_,

        member0_.team_id as team_id5_5_0_,

        member0_.name as name6_5_0_,

        member0_.edDate as eddate7_5_0_,

        member0_.stDate as stdate8_5_0_ 

    from

        Member member0_ 

    where

        member0_.MEMBER_ID=?

17:24:03.207 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl - On call to EntityIdentifierReaderImpl#resolve, EntityKey was already known; should only happen on root returns with an optional identifier specified

17:24:03.209 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [jpabasic.hellojpa.Member#1]

17:24:03.209 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `addressHistory` : value = NOT NULL COLLECTION

17:24:03.209 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`addressHistory`)  - enhanced for lazy-loading? - false

17:24:03.211 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `favoriteFoods` : value = NOT NULL COLLECTION

17:24:03.211 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`favoriteFoods`)  - enhanced for lazy-loading? - false

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `homeAddress` : value = [Ljava.lang.Object;@3ebe4ccc

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`homeAddress`)  - enhanced for lazy-loading? - false

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `team_id` : value = null

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`team_id`)  - enhanced for lazy-loading? - false

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `username` : value = 서울역

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`username`)  - enhanced for lazy-loading? - false

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `workPeriod` : value = null

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`workPeriod`)  - enhanced for lazy-loading? - false

17:24:03.212 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [jpabasic.hellojpa.Member#1]

17:24:03.212 [main] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : jpabasic.hellojpa.Member#1

17:24:03.216 [main] DEBUG org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer - Loading collection: [jpabasic.hellojpa.Member.favoriteFoods#1]

17:24:03.216 [main] DEBUG org.hibernate.SQL - 

    select

        favoritefo0_.MEMBER_ID as member_i1_3_0_,

        favoritefo0_.FOOD_NAME as food_nam2_3_0_ 

    from

        FAVORITE_FOOD favoritefo0_ 

    where

        favoritefo0_.MEMBER_ID=?

17:24:03.218 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl - Preparing collection initializer : [jpabasic.hellojpa.Member.favoriteFoods#1]

17:24:03.223 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl - Found row of collection: [jpabasic.hellojpa.Member.favoriteFoods#1]

17:24:03.223 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl - Found row of collection: [jpabasic.hellojpa.Member.favoriteFoods#1]

17:24:03.223 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl - Found row of collection: [jpabasic.hellojpa.Member.favoriteFoods#1]

17:24:03.223 [main] DEBUG org.hibernate.engine.loading.internal.CollectionLoadContext - 1 collections were found in result set for role: jpabasic.hellojpa.Member.favoriteFoods

17:24:03.224 [main] DEBUG org.hibernate.engine.loading.internal.CollectionLoadContext - Collection fully initialized: [jpabasic.hellojpa.Member.favoriteFoods#1]

17:24:03.224 [main] DEBUG org.hibernate.engine.loading.internal.CollectionLoadContext - 1 collections initialized for role: jpabasic.hellojpa.Member.favoriteFoods

17:24:03.224 [main] DEBUG org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer - Done loading collection

===============ENTITY====================

17:24:03.224 [main] DEBUG org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer - Loading collection: [jpabasic.hellojpa.Member.addressHistory#1]

17:24:03.224 [main] DEBUG org.hibernate.SQL - 

    select

        addresshis0_.MEMBER_ID as member_i5_0_0_,

        addresshis0_.id as id1_0_0_,

        addresshis0_.id as id1_0_1_,

        addresshis0_.city as city2_0_1_,

        addresshis0_.street as street3_0_1_,

        addresshis0_.zipcode as zipcode4_0_1_ 

    from

        ADDRESS addresshis0_ 

    where

        addresshis0_.MEMBER_ID=?

17:24:03.226 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl - Preparing collection initializer : [jpabasic.hellojpa.Member.addressHistory#1]

17:24:03.226 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - rolling back

17:24:03.229 [main] DEBUG org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl - Initiating JDBC connection release from afterTransaction

17:24:03.229 [main] DEBUG org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl - Initiating JDBC connection release from afterTransaction

17:24:03.229 [main] WARN org.hibernate.engine.loading.internal.LoadContexts - HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@4ee25d80<rs=rs39: null>

17:24:03.230 [main] WARN org.hibernate.engine.loading.internal.CollectionLoadContext - HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries

17:24:03.230 [main] DEBUG org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl - HHH000420: Closing un-released batch

17:24:03.230 [main] DEBUG org.hibernate.internal.SessionFactoryImpl - HHH000031: Closing

17:24:03.231 [main] DEBUG org.hibernate.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@16a35bd] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@5eccd3b9]

17:24:03.232 [main] DEBUG org.hibernate.service.internal.AbstractServiceRegistryImpl - Implicitly destroying ServiceRegistry on de-registration of all child ServiceRegistries

17:24:03.232 [main] INFO org.hibernate.orm.connections.pooling - HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/hellojpa]

17:24:03.234 [main] DEBUG org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl - Implicitly destroying Boot-strap registry on de-registration of all child ServiceRegistries

 

Process finished with exit code 0

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

주의: 업로드시 권한 문제 꼭 확인해주세요

0

genesis님의 프로필 이미지
genesis
질문자

try {

Movie movie = new Movie();
movie.setDirector("장항선");
movie.setActor("황정민");
movie.setName("킹덤");
movie.setPrice(10000);

em.persist(movie);

em.flush();
em.clear();

Movie findmv = em.find(Movie.class, movie.getId());
System.out.println("find Movie = " + findmv.getName());

Member member = new Member();
member.setUsername("서울역");
member.setHomeAddress(new Address("서울", "서울로", "123-456"));

member.getFavoriteFoods().add("chicken");
member.getFavoriteFoods().add("pizza");
member.getFavoriteFoods().add("ddukbbokkki");

member.getAddressHistory().add(new AddressEntity("구미", "도량동", "123456"));
member.getAddressHistory().add(new AddressEntity("포항", "두호동", "999888"));

em.persist(member);

em.flush();
em.clear();

System.out.println("===============START====================");
Member findmember = em.find(Member.class, member.getId());

findmember.setUsername("서초맨");

Address newAddress = new Address("서초구", "THE H APT", "688987");
findmember.setHomeAddress(newAddress);

//chicken --> black noodle
findmember.getFavoriteFoods().remove("chicken");
findmember.getFavoriteFoods().add("black noodle");

//도량동 --> 봉곡동
// 값타임 컬렉션 일 경우에 값을 변경하는 방법 : 비추.
//findmember.getAddressHistory().remove(new AddressEntity(new Address("구미", "도량동", "123456")));
//findmember.getAddressHistory().add(new AddressEntity(new Address("구미", "봉곡동", "654321")));


System.out.println("===============ENTITY====================");

// 값타입을 래핑한 엔티티 타입일 경우, 값을 변경하는 방법
//
// findmember.getAddressHistory().remove(0);
findmember.getAddressHistory().get(0).getAddress().setCity("봉곡동");
//findmember.getAddressHistory().add(new AddressEntity(new Address("구미", "봉곡동", "654321")));


tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}


위와 같이 했을 때, 저는 결과가 반영이 되지 않습니다.
로그를 봐도 어데이트 쿼리도 나가지 않습니다.

아래는 로그입니다.

엔티티쪽 코드도 살펴봐야겠네요.

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

주의: 업로드시 권한 문제 꼭 확인해주세요

0

genesis님의 프로필 이미지
genesis
질문자

System.out.println("===============START====================");
Member findmember = em.find(Member.class, member.getId());
findmember.setUsername("서초맨");
Address newAddress = new Address("서초구", "THE H APT", "688987");
findmember.setHomeAddress(newAddress);
//chicken --> black noodle
findmember.getFavoriteFoods().remove("chicken");
findmember.getFavoriteFoods().add("black noodle");
//도량동 --> 봉곡동
// 값타임 컬렉션 일 경우에 값을 변경하는 방법 : 비추.
//findmember.getAddressHistory().remove(new AddressEntity(new Address("구미", "도량동", "123456")));
//findmember.getAddressHistory().add(new AddressEntity(new Address("구미", "봉곡동", "654321")));
System.out.println("===============ENTITY====================");
// 값타입을 래핑한 엔티티 타입일 경우, 값을 변경하는 방법 ==>> 이 부분이 해결이 부분입니다.
//
findmember.getAddressHistory().remove(0);
findmember.getAddressHistory().add(new AddressEntity(new Address("구미", "봉곡동", "654321")));
tx.commit();

이렇게 코드를 실행하셨을 때 어떤 결과가 나오는지도 함께 올려주실 수 있으세요?

그리고 본인이 예상했던 결과와 어떻게 다른지도 알려주세요:)

1. 값타입을 엔티티로 승급시킵니다.

2. "Seoul"이라는 값을 가지는 AddressEntity를 member에 추가하고 저장합니다.

3. 저장 후 다시 Member를 불러와서 AddressEntity를 수정합니다.

4. Seoul에서 Busan으로 변경된 것을 확인할 수 있습니다.

 

Seoul이 Busan으로 변경되었기 때문에 update 쿼리가 한 번 더 나가는 것을 확인할 수 있습니다.

0

안녕하세요. genesis님, 공식 서포터즈 David입니다.

.
genesis님께서 직접 확인해보려고 하셨던 코드를 보여주실 수 있으실까요?

제가 그냥 알려드리는 것보다 직접 작성하신 코드를 바탕으로 말씀드리는게 더욱 도움이 되실 것 같아서요:)
.
감사합니다.

genesis님의 프로필 이미지
genesis
질문자

System.out.println("===============START====================");
Member findmember = em.find(Member.class, member.getId());
findmember.setUsername("서초맨");
Address newAddress = new Address("서초구", "THE H APT", "688987");
findmember.setHomeAddress(newAddress);
//chicken --> black noodle
findmember.getFavoriteFoods().remove("chicken");
findmember.getFavoriteFoods().add("black noodle");
//도량동 --> 봉곡동
// 값타임 컬렉션 일 경우에 값을 변경하는 방법 : 비추.
//findmember.getAddressHistory().remove(new AddressEntity(new Address("구미", "도량동", "123456")));
//findmember.getAddressHistory().add(new AddressEntity(new Address("구미", "봉곡동", "654321")));
System.out.println("===============ENTITY====================");
// 값타입을 래핑한 엔티티 타입일 경우, 값을 변경하는 방법 ==>> 이 부분이 해결이 부분입니다.
//
findmember.getAddressHistory().remove(0);
findmember.getAddressHistory().add(new AddressEntity(new Address("구미", "봉곡동", "654321")));
tx.commit();
genesis님의 프로필 이미지

작성한 질문수

질문하기