line / kotlin-jdsl

Kotlin library that makes it easy to build and execute queries without generated metamodel
https://kotlin-jdsl.gitbook.io/docs/
Apache License 2.0
651 stars 85 forks source link

Fetch Join시 Select절 entity() 유무에 따른 동작 방식 차이 #727

Closed sjnqkqh closed 1 week ago

sjnqkqh commented 1 week ago

안녕하세요.

최근 Kotlin-jdsl을 어느 정도 사용하고 신규 사용자를 위한 몇 가지 팁을 작성하면서, 확인해주셨으면 하는 내용이 있어 문의드립니다.


image image
# 생성된 SQL 예시
    SELECT
          r1_0.*,
          t1_0.*
   FROM
           tb_reddit r1_0 
   JOIN 
           tb_reddit_translate tl1_0 
    ON r1_0.id=tl1_0.reddit_id

SELECT절 Entity 포함 여부에 따른 결과값 차이 - Diffchecker


  1. 그래서 위 동작 방식이 구현의도와 일치하는지, 혹은 Issue로 추후 처리될지 질문드리고 싶습니다.
  2. 며칠간 kotlin-jdsl을 사용해보며, 새로 kotlin-jdsl을 사용하기 시작하는 사용자를 위한 팁을 몇 가지 작성해봤습니다. 혹시 시간이 되시면 내용 중 틀린 부분이나 추후 변경될 부분이 있을지 한번만 확인해주실 수 있으실까요? Kotlin Jdsl과 춤을 - 사소한 팁 d57873ae79a24f1b98dd142d8012bde5.pdf
  3. kotlin-jdsl에 컨트리뷰터로 기여하고 싶은데, 혹시 첨부한 파일에 작성한 내용 중 공식 Docs에 추가될만한 내용이 있을지 궁금합니다.
shouwn commented 1 week ago

먼저 Kotlin JDSL에 관심을 가져주시고 이렇게 정리까지 해주셔서 감사합니다!

  1. SELECT 문에 2개의 Entity를 조회하는 케이스를 고려하지 않았습니다. JPQL로 조회할 때 2개의 Entity가 SELECT 문에 들어갈 수 있다는 것을 처음 알게 되었습니다. 지금까지 저는 2개의 Entity를 한번에 조회한 적이 없었기 때문입니다. 그렇기 때문에 제가 다음에 말씀드리는 내용은 틀렸을 수 있습니다. 저는 Reddit과 Translate 2개를 같이 조회한다면 10개의 결과값이 나오는 게 맞다고 생각합니다. RDB로 생각해보면, 두 테이블을 조인했을 때 두 테이블 사이의 모든 조합이 ROW로 표현됩니다. JPA 또한 이 방식을 그대로 가져왔다고 생각합니다. sjnqkqh 님께서는 Reddit을 Root Entity라고 생각하시기 때문에 3개의 결과 값을 기대하고 계시지만 쿼리만 보았을 때는 Reddit과 Translate 사이에 상하관계는 존재하지 않습니다. Reddit, Translate 2개를 조회할 때 3개만 나온다면, Translate 10개 중 어떤 3개를 뽑아야 할지 라이브러리는 알지 못합니다.

2-1. Join 절의 ON 조건으로 entity를 사용할 수 없는 것은 버그입니다. JpqlEntitySerializer.kt에 ON을 같이 고려했어야 했는데 그러지 못 했네요. 보통 entity가 조건으로 들어갈 때에는 relation을 통해 JOIN을 하다 보니 이 부분을 놓쳤습니다. 혹시 관심 있으시면 이 부분을 직접 수정해보시는 건 어떨까요? Kotlin JDSL의 코어 부분을 아셔야 하기 때문에 조금 난이도가 있어 힘드시면 말씀주세요! 제가 추후에 수정하도록 하겠습니다.

2-2. 말씀해주신 것처럼 JpqlRenderContext를 Spring Bean으로 등록하는 것을 추천드립니다. 하지만 spring-data-jpa-support 모듈을 추가하시면 AutoConfigure에 JpqlRenderContext를 Bean으로 등록하기 때문에 꼭 작성해주실 필요는 없습니다.

2-3. Fetch Join을 사용하기 위해 Select 절에 Fetch 대상 entity를 사용하는 것은 추천드리지 않습니다. select 절에는 조회하고 싶은 대상만 나열하고, 그 대상을 어떻게 조회할 것인지를 from에서 fetch join으로 표현하는 것을 추천드립니다. 즉 fetch join을 위해서는 FROM절에 fetchJoin 메서드만 사용하는 것을 추천드립니다.

  1. 작성해주신 내용은 블로그 포스트로는 좋지만 Docs에 추가하기에는 아쉬운 내용으로 보입니다. 가끔 제가 Kotlin JDSL을 구글에 검색해보는데 블로그 포스트로 올려주시면 표현하지 않지만 내심 정말 기뻐하기 때문에 블로그 포스트로 올려주시면 정말 감사하겠습니다!
sjnqkqh commented 1 week ago

상세한 답변 감사합니다! 2-1에 언급해주신 부분은 가능하면 제가 수정해보겠습니다. 추가적인 문의 사항은 없으므로 이슈 클로징하겠습니다. 감사합니다!

shouwn commented 1 week ago

넵 혹시 작업하시다가 내부 구조에 대해 궁금한 내용이 있으시면 디스코드로 말씀주세요.