cheese10yun / blog-comment

0 stars 0 forks source link

JPA 영속성 컨텍스트 주의 점 - Yun Blog | 기술 블로그 #43

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

JPA 영속성 컨텍스트 주의 점 - Yun Blog | 기술 블로그

Yun Blog | 기술 블로그

https://cheese10yun.github.io/jpa-persistent-context/

joseph415 commented 3 years ago

안녕하세요! 글 유익하게 잘 읽었습니다! 그런데 질문이 있는데 jpql 사용시 영속성 컨텍스트를 거치지 않고 바로 디비에 조회하는데 그전에 jpql을 사용하면 flush.auto가 디폴트로 설정되어있어 flush를 하는걸로 알고 있는데

테스트에 실패를 하는 이유가 적절하지 않은 것 같아 질문남깁니다 flush가 된다면 디비와 싱크가 맞을 것이고.. 그렇다면 테이블에 데이터가 insert 되어 적잘한 값을 가져와야하지 않나요?

joseph415 commented 3 years ago

원래 알고 있던 내용과 혼동이 었었네요.. 글을 다시 읽고 이해가 되었습니다ㅎㅎ 영속성컨텍스트에 객체가 존재해서 조회한 데이터가 버려지게 된다는 부분을 놓쳤네요! 좋은 글 감사합니다!

cheese10yun commented 3 years ago

@joseph415

네 맞습니다. JPQL는 데이터베이스에 SQL을 날려 데이터를 가져오지만 영속성 컨텍스트에 동일한 값이 있다면 (동일한 판단은 @Id 의 값으로 판단) 디비에서 가져온 값을 버리게 됩니다.

조금더 첨언 하자면 양방향 편의메서드를 만들어 영속화 하기전 객체를 연결하는 해당 문제는 발생하지 않습니다. Team 객체에 Member 추가하기와 비슷한 맥락입니다.

underdarks commented 1 year ago

안녕하세요! 궁금한게 있어서 댓글남깁니다. 본문에서 " findById 같은 같은 경우 1차 캐시를 먼저 조회 후 없으면 DB에서 가져옴 JPQL은 반대로 영속성 컨텍스트를 먼저 조회하지 않고 DB에 쿼리를 날려 결과를 가져온다" 라고 언급하셨는데 findById는 쿼리 메소드로 알고 있는데 결국 JPQL로 실행되지 않나요? 그런데 왜 프로세스가 다른지 궁금합니다!

cheese10yun commented 1 year ago

@underdarks Spring Data JPA에서 제공해 주는 findById도 쿼리 메서드인 건 맞고 결국 그게 JPQL로 컨버팅되는 것으로 생각이 됩니다.(이 부분은 틀린 수도 있습니다.)

그러면 핵심은 findById와, JPQL(findById도 결국 JQPL으로 볼 수 있지만 여기서는 FK 기반 조회와, 그렇지 않은 조회를 JPQL이라고 정의하겠습니다.) 동작 메커니즘이 왜 다르냐일 거 같은데요.

JPA JPQL의 조회 동작 살펴보기에서 자세하게 포스팅한 적 있습니다. 쉽게 요약하면 데이터베이스 격리 수준을 애플리케이션 레벨에서 REPEATABLE 수준까지 올리게 하기 위해 그러한 프로세스로 동작하는 것입니다.

물론 애플리케이션 레벨에서 보장하는 것이기 때문에 이것을 믿고 데이터베이스 격리 수준을 변경하는 것을 권장하지는 않습니다. 대부분 디비 기본 격리 수준을 준수하는 것이 좋다고 생각합니다.