• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

em.find 시 쿼리문 2번 수행

23.07.04 20:26 작성 조회수 186

0

답변 없으셔서 다시 남깁니다.

 

영속성 컨텍스트 2 강의의 약 7분 쯤 em.find를 2번하게 되어도 1차캐시 조회에 의해 쿼리문이 한번만 출력된다고 하셨는데

저는 2번 출력되네요.. 문제가 뭘까요

 

https://drive.google.com/drive/folders/1rLlWTlGVWyFRoL-HXbvyWREnpHBC7OBe?usp=sharing

 

추가로 질문이 하나 더 있는데

강의에서는 JPAMain 자바 파일의 try문을 수행하면 db에 바로 저장이 되는데
저는 저장이 안됩니다.

이것도 한번 확인 부탁드립니다.

답변 1

답변을 작성해보세요.

0

y2gcoder님의 프로필

y2gcoder

2023.07.05

안녕하세요. 94leehd님, 공식 서포터즈 y2gcoder입니다.

먼저 올려주셨던 질문에 대해 답을 얻지 못해서 다시 질문을 올리게 하는 불편을 겪게 만든 점 죄송합니다.

올려주신 코드 잘 읽어보았습니다!

두 가지 질문을 해주셨는데, em.find() 쿼리가 2번 나가는 문제, 그리고 JPAMain을 실행했을 때 DB에 바로 저장이 되지 않는다는 문제에 대해서 질문해주셨습니다.

원인은 persistence.xml입니다.

<property name="hibernate.hbm2ddl.auto" value="create" />

해당 옵션의 주석이 풀려있었습니다. 해당 옵션은 쉽게 생각하시면 서버가 시작할 때마다 해당 DB의 테이블을 날리고 다시 만드는 옵션입니다. 아직 영속성 컨텍스트 2 강의까지는 주석처리되어있기 때문에 주석처리해주셔야 강의와 똑같이 진행하실 수 있습니다.

그러면 해당 옵션을 정상적으로 주석처리 후 영속성 컨텍스트 2의 초반부 강의를 따라가본 후 주셨던 질문에 같이 대답해드리도록 하겠습니다.

  1. h2 DB에 member 테이블이 있는 상태입니다.

image

  1. persistence.xml에 hibernate.hbmddl.auto 옵션을 주석처리합니다.

image

  1. 먼저 id 100인 member를 생성합니다.

image(Insert 쿼리가 잘 나갔고)

image(DB에도 잘 들어간 모습을 볼 수 있습니다.)

  1. 이제 말씀하셨던 em.find()를 두 번 실행해보겠습니다.

image(select 쿼리가 한 번 나간 것을 볼 수 있습니다.)

결국 JpaMain을 실행할 때마다 Member 테이블이 지워졌다가 다시 만들어졌기 때문에 위의 두 현상을 겪으신 것으로 보입니다. 항상 insert를 먼저 하셨지만, em.find()를 두 번 호출하려고 다시 JpaMain을 실행하시면 @Entity가 붙어있는 Member와 매핑되어있는 테이블이 MEMBER기 때문에 위에 주석을 풀었던 create 옵션에 의해 MEMBER 테이블이 재생성됩니다. 그러면 이전에 Insert 했던 member 데이터는 날아가기 때문에 테이블은 비어있게 되는 것입니다.

또한 em.find() 입장에서도 데이터베이스에 100 이라는 id를 가진 데이터가 있어야 1차캐시에 넣을 수 있습니다. 그리고 1차캐시에 id 100인 member 객체가 들어있어야 다음 줄의 동일한 id를 가진 member를 찾기 위한 em.find()에서 select 문이 날아가지 않습니다. 하지만 두번째 em.find()를 할 때 이전 em.find()에서 1차캐시에 원하는 데이터를 저장해놓지 못했기 때문에 두번째 em.find() 또한 데이터베이스에서 찾기 위해 다시 select 쿼리를 날리게 되고, 결과적으로 select 문이 2번 발생하게 됩니다.

 

감사합니다.