Spring/JPA

QueryDSL과 1차 캐시 의문점

묠니르묘묘 2022. 12. 6. 21:15

QueryDSL이 무엇인지 궁금하시다면 아래 더보기를 눌려주세요.

더보기

QueryDSL이란?

오픈소스 프로젝트로 JPQL을 Java 코드로 작성할 수 있게 해주는 라이브러이다.

 

왜 사용하는가?

Spring Data JPA를 사용하여 CRUD 및 여러 쿼리 메서드 기능을 사용하더라도 결국 커스텀한 쿼리가 필요하게 된다. 이 때 JPQL을 사용하게 되는데 복잡한 로직의 경우 쿼리 문자열이 상당히 길어져서 매우 복잡해진다. JPQL을 잘못작성하더라도 해당 쿼리를 실행하게 되는 코드가 클라이언트(사용자)에 의해서 사용되지 않으면 알 수가 없다. 이러한 문제점을 해결해주고 여러 편의성을 제공한다.

 

  • JPA를 사용할 때 동적 쿼리와 복잡한 쿼리 문제 해결 가능
  • 쿼리를 문자가 아닌 자바 코드로 작성 가능
  • 문법 오류를 런타임이 아닌 컴파일 시점에서 발견
  • 매우 깔끔한 DTO 조회 지원

 

의문점

🚀 QueryDSL로 2번 조회하면 2번의 SQL문이 실행되는데, JPA의 영속성 컨텍스트 1차 캐시가 있는데 왜 2번 실행될까?

 

QueryDSL은 JPQL 빌더이지 JPA가 아니다. 내가 착각했던 부분이다. em.find()는 EntityManager가 조회하는 것으로 영속성 컨텍스트에서 먼저 찾게되지만, JPQL의 경우 항상 SQL로 번역되어서 우선 실행이 된다. 따라서 QueryDSL로 조회를 하면 아래 과정을 거치게 된다.

  • JPQL을 호출하면 DB를 우선적으로 조회
  • 조회한 값을 영속성 컨텍스트에 저장하려고 시도
  • 영속성 컨텍스트에 해당 데이터가 있는 경우, 조회결과를 버리고 영속성 컨텍스트의 값을 반환

이 때 영속성 컨텍스트는 Entity 객체의 일관성을 보장해야하므로 DB 조회값을 버리고 원래 가지고 있던 값을 반환하게 되는 것이다.