inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Trong thực tế! Phát triển ứng dụng quản lý thư viện với Kotlin và Spring Boot (tái cấu trúc dự án Java)

hibernate가 select를 두번 하는 이유

Đã giải quyết

240

paris7159206

1 câu hỏi đã được viết

0

안녕하세요 강사님 강의를 들으면서 이번에 처음 JPA를 알아가고 있는 중입니다.

헌데 궁금한점이 JPA 특성인것인지 아니면 H2 DB 문제인지 그것도 아니면 제 Intellij 설정 문제인지 모르겠지만 select가 두번이 되는 이유가 무엇때문이지 궁금해서 질문 드립니다.

 

실질적인 동작에 문제가 생기지는 않겠지만 N+1 관련 강의를 듣다보니 불필요하게 쿼리가 호출되면 안좋은것 같아 여쭈어 봅니다.

 

 

    @Test
    @DisplayName("대출 기록이 없는 유저도 응답에 포함")
    fun getUserLoanHistoriesTest() {
        //given
        userRepository.save(User("A",null))

        //when
        val results = userService.getUserLoanHistories()

        //then
        assertThat(results).hasSize(1)
        assertThat(results[0].name).isEqualTo("A")
        assertThat(results[0].books).isEmpty()

    }

위의 코드를 동작시켰을때

Hibernate: 
    insert 
    into
        user
        (id, age, name) 
    values
        (default, ?, ?)
Hibernate: 
    select
        user0_.id as id1_1_,
        user0_.age as age2_1_,
        user0_.name as name3_1_ 
    from
        user user0_
Hibernate: 
    select
        userloanhi0_.user_id as user_id4_2_0_,
        userloanhi0_.id as id1_2_0_,
        userloanhi0_.id as id1_2_1_,
        userloanhi0_.book_name as book_nam2_2_1_,
        userloanhi0_.status as status3_2_1_,
        userloanhi0_.user_id as user_id4_2_1_ 
    from
        user_loan_history userloanhi0_ 
    where
        userloanhi0_.user_id=?
Hibernate: 
    select
        user0_.id as id1_1_,
        user0_.age as age2_1_,
        user0_.name as name3_1_ 
    from
        user user0_
Hibernate: 
    select
        userloanhi0_.user_id as user_id4_2_0_,
        userloanhi0_.id as id1_2_0_,
        userloanhi0_.id as id1_2_1_,
        userloanhi0_.book_name as book_nam2_2_1_,
        userloanhi0_.status as status3_2_1_,
        userloanhi0_.user_id as user_id4_2_1_ 
    from
        user_loan_history userloanhi0_ 
    where
        userloanhi0_.user_id=?
Hibernate: 
    delete 
    from
        user 
    where
        id=?

출력 부분에 위에 처럼 뜨는데요

제가 이해한 바로는 insert는 save 때문에 한번인 반면에

getUserLoanHistoreies 부분에 findAll로 한번의 쿼리를 불러오는 거라서 user와 와 userloanhistory 테이블을 각각 한번 씩 조회 해야 하지 않는가 싶어서 질문 드립니다.

추가로 확인해 보보니 LEFT join에 fetch를 추가했을때 위의 select user와 user_loan_history는 left join 쿼리문으로 변한는 반면 아래의 select user와 user_loan_history는 남아 있습니다. 따로 user를 find 하는 곳이 없는 것 같은데 이런 현상이 나오는 이유가 뭘까요?.... 추측 하기로는 AfterEach로 clear할때 deleteAll을 사용해서 사용했던 테이블을 모두 select 하는건가 싶긴 한데... 제가 이해를 잘 못해서 그런건지 이부분이 어렵네요....

java spring kotlin spring-boot 리팩토링

Câu trả lời 1

1

lannstark

안녕하세요 민승님!! 🙂

좋은 질문 감사드립니다. 추측해주신 것처럼 deleteAll() 을 하는 부분에서 실제 바로 delete를 하는게 아니라 대상 테이블 조회 + 연관관계 테이블 조회를 한 이후에 id를 이용해 delete를 진행하는게 맞습니다.

즉, 테스트에 사용한 데이터를 지우는 부분에서 select를 활용한게 맞을거에요!

 

보다 정확히는 @AferEach 에서 본격적으로 delete가 되기 전, println("삭제 시작") 같은 출력을 해보시면, Hibernate 로그가 나오기 전에 <삭제 시작> 문구가 나오는지를 기준으로 확인해보실 수 있을겁니다!

답변이 도움이 되었으면 좋겠습니다. 감사합니다! 🙏

안녕하세요 혹시 프론트 코드 제공받을 수 있을까요?

0

68

2

실행이 안되네요

0

66

2

프론트 영역 보는법

0

51

2

companion object

0

78

2

Custom 레프직토리 형식

0

57

2

Querydsl 도입

0

67

2

fetch join DISTINCT 중복제거

1

83

2

표준 예외와 커스텀 예외 사용 전략 질문

0

86

3

이 질문이 왜 없는지 이해가 안 되지만 문제 인식 및 해결 방법 남깁니다.

1

177

2

테스트를 위한 코드

1

105

2

프로젝트 실행 에러

0

151

2

PDF 문서에 오타가 있어서 알려드립니다.

1

102

1

enum질문

1

86

1

테스트 후 AfterEach 함수에서 나오는 쿼리

0

136

2

테스트 fixture

1

210

2

./gradlew test 실행시 인식할수 없다고 뜹니다.

0

140

1

test 코드 실행시 경고가 발생합니다.

0

140

1

13강 User Kotlin 변환중

2

169

3

'추가 - 코프링과 플러그인' 강의 7:46 allopen 관련 질문

2

174

1

-

0

141

2

4:28 build.gradle 수정 시 kotlin-reflect관련 implementation 추가 해야할까요?

0

312

3

junit import 불가

0

271

3

테스트 코드와 관련하여 질문이 있습니다.

1

218

1

intelliJ 최신버전과 kotlin 1.6버전 충돌. 빌드 오류

1

1002

2