From 0b9fc941a280aa5243772aa49f3402367df442be Mon Sep 17 00:00:00 2001 From: progress0407 Date: Mon, 8 Apr 2024 00:05:24 +0900 Subject: [PATCH 1/3] docs: write 'Why does Kotlin JDSL allow nullable return types' document --- ...lable-list-in-the-spring-support-module.md | 39 +++++++++++++++++++ ...lable-list-in-the-spring-support-module.md | 39 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md create mode 100644 docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md diff --git a/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md b/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md new file mode 100644 index 000000000..cefb77a7b --- /dev/null +++ b/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md @@ -0,0 +1,39 @@ +# Why does Kotlin JDSL allow nullable return types? + +Kotlin JDSL helps developers develop more efficiently by allowing them to write queries without creating a separate metadata model or making string syntax errors. +However, Kotlin JDSL users may sometimes have questions about nullable return types in the form of Slice or Page returned when calling APIs like findSlice or findPage methods. + +## Why do we need nullable return types? + +The reason why Kotlin JDSL supports nullable return types is that depending on how the JPQL query is written, some of the returned list items may contain null values. +The simplest example is when you look up a column or entity without using DTO Projection. + +The table below shows some of the cases where nullable return types can occur when using the Kotlin JDSL. + +| Item | Nullable or not | Reason | +|----------------|-----------------|------------------------------------------------------------------------------------------------------| +| DTO Projection | X | Calling the constructor for all ROWs results in the object being created, which does not allow nulls | +| Column | O | Exists when looking up a field that is null | +| Entity | O | Exists if the Entity being joined on Left Join is null. | + +As another example, the code below shows a situation where the Author entity exists, but the BookAuthor entity, the target of the left join, may be null. + +```kotlin +val query = jpql { + select( + path(BookAuthor), + ).from( + entity(Author::class), + leftJoin(BookAuthor::class).on(path(Author::authorId).equal(path(BookAuthor::authorId))), + ) +} +``` + +## Background on the design decision + +In the early development of Kotlin JDSL 3.0, we tried nullable inference. +This was an attempt to automatically infer whether a query result is nullable through the type system. +However, during the development of queries that use JOIN, we encountered the problem that perfect nullable inference was not possible. + +Starting with Kotlin JDSL 3.0, we're settling on a path that utilizes the user's query writing knowledge as much as possible, with a small learning curve. +This avoids confusion due to different interfaces for different users, and allows them to build on their existing JPQL knowledge without having to learn Kotlin JDSL syntax separately. diff --git a/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md b/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md new file mode 100644 index 000000000..8cfb2cde3 --- /dev/null +++ b/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md @@ -0,0 +1,39 @@ +# 왜 Kotlin JDSL은 nullable한 반환 타입을 허용하나요? + +Kotlin JDSL을 사용하면 별도의 메타데이터 모델 생성이나 문자열 문법 오류 없이 쿼리를 작성할 수 있도록 도와주어 개발자가 보다 효율적으로 개발할 수 있게 도와줍니다. +그러나 Kotlin JDSL 사용자는 때때로 findSlice나 findPage 메소드 같은 API 호출 시 반환되는 Slice 또는 Page 형태의 nullable 반환 타입에 대해 궁금증을 가질 수 있습니다. + +## Nullable 반환 타입의 필요성 + +Kotlin JDSL이 nullable한 반환 타입을 지원하는 이유는 JPQL 쿼리의 작성 방법에 따라 반환되는 리스트 항목 중 null 값이 포함될 수 있기 때문입니다. +가장 간단한 예로는 DTO Projection을 사용하지 않고, column이나 entity를 조회할 때를 들 수 있습니다. + +아래 표는 Kotlin JDSL을 사용할 때 nullable한 반환 타입이 발생할 수 있는 몇 가지 경우를 나타냅니다. + +| 항목 | null 여부 | 이유 | +|----------------|---------|---------------------------------------------------------| +| DTO Projection | X | 모든 ROW에 대한 생성자 호출하기 때문에 객체가 생성되어 null을 허용하는 결과가 나오지 않음 | +| Column | O | null인 필드를 조회하는 경우 존재 | +| Entity | O | Left Join시 조인의 대상이 되는 Entity가 null인 경우 존재 | + +또 다른 예로 아래 코드는 Author 엔티티가 있지만, left join의 대상인 BookAuthor 엔티티는 null일 수 있는 상황을 보여줍니다. + +```kotlin +val query = jpql { + select( + path(BookAuthor), + ).from( + entity(Author::class), + leftJoin(BookAuthor::class).on(path(Author::authorId).equal(path(BookAuthor::authorId))), + ) +} +``` + +## 설계 결정의 배경 + +초기 Kotlin JDSL 3.0 개발 시에는 nullable 추론을 시도했습니다. +이는 쿼리 결과의 nullable 여부를 타입 시스템을 통해 자동으로 추론하려는 시도였습니다. +하지만, join을 사용하는 쿼리의 개발 과정에서 완벽한 nullable 추론이 불가능하다는 문제에 직면했습니다. + +Kotlin JDSL 3.0부터는 되도록 사용자가 알고 있는 쿼리 작성 지식만을 활용해서 적은 러닝 커브로 사용할 수 있게 하는 노선으로 정착합니다. +이는 사용자가 바라보는 인터페이스가 각자 달라 혼란을 방지하고, Kotlin JDSL 문법을 별도로 학습할 필요 없이 기존의 JPQL 지식을 기반으로 활용할 수 있게 합니다. From 4a1328740e4de546cef67e8151eec0308b9a298e Mon Sep 17 00:00:00 2001 From: progress0407 Date: Mon, 22 Apr 2024 16:13:57 +0900 Subject: [PATCH 2/3] docs: reflect reviews --- ...ullable-list-in-the-spring-support-module.md | 17 +++++++++-------- ...ullable-list-in-the-spring-support-module.md | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md b/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md index cefb77a7b..6205da221 100644 --- a/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md +++ b/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md @@ -1,7 +1,8 @@ # Why does Kotlin JDSL allow nullable return types? -Kotlin JDSL helps developers develop more efficiently by allowing them to write queries without creating a separate metadata model or making string syntax errors. -However, Kotlin JDSL users may sometimes have questions about nullable return types in the form of Slice or Page returned when calling APIs like findSlice or findPage methods. +Kotlin JDSL helps you write queries in a type-safe way. +You may wonder if it also allows non-null data to be null when returning a bunch of data (e.g. `Slice` in `findSlice`, `Page` in `findPage`). +This article explains why the Kotlin JDSL allows nullable return types. ## Why do we need nullable return types? @@ -10,11 +11,11 @@ The simplest example is when you look up a column or entity without using DTO Pr The table below shows some of the cases where nullable return types can occur when using the Kotlin JDSL. -| Item | Nullable or not | Reason | -|----------------|-----------------|------------------------------------------------------------------------------------------------------| -| DTO Projection | X | Calling the constructor for all ROWs results in the object being created, which does not allow nulls | -| Column | O | Exists when looking up a field that is null | -| Entity | O | Exists if the Entity being joined on Left Join is null. | +| Item | Nullable or not | Reason | +|----------------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| +| DTO Projection | X | Calling the constructor for all ROWs did not result in the object being created to allow nulls.
Fields in DTO can be null, but DTO object cannot be null. | +| Column | O | Exists when looking up a field that is null. | +| Entity | O | Exists if the Entity being joined on Left Join is null. | As another example, the code below shows a situation where the Author entity exists, but the BookAuthor entity, the target of the left join, may be null. @@ -24,7 +25,7 @@ val query = jpql { path(BookAuthor), ).from( entity(Author::class), - leftJoin(BookAuthor::class).on(path(Author::authorId).equal(path(BookAuthor::authorId))), + leftJoin(BookAuthor::class).on(path(Author::authorId).equal(path(BookAuthor::authorId))) ) } ``` diff --git a/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md b/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md index 8cfb2cde3..11a657dcc 100644 --- a/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md +++ b/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md @@ -1,7 +1,8 @@ -# 왜 Kotlin JDSL은 nullable한 반환 타입을 허용하나요? +# 왜 Kotlin JDSL은 Nullable한 반환 타입을 허용하나요? -Kotlin JDSL을 사용하면 별도의 메타데이터 모델 생성이나 문자열 문법 오류 없이 쿼리를 작성할 수 있도록 도와주어 개발자가 보다 효율적으로 개발할 수 있게 도와줍니다. -그러나 Kotlin JDSL 사용자는 때때로 findSlice나 findPage 메소드 같은 API 호출 시 반환되는 Slice 또는 Page 형태의 nullable 반환 타입에 대해 궁금증을 가질 수 있습니다. +Kotlin JDSL을 사용하면 Type Safe하게 쿼리를 작성할 수 있게 도와주지만 +다건의 데이터를 반환할 때 non-null한 데이터 또한 null을 허용하는지 궁금증을 가질 수 있습니다. (예를 들어 `findSlice`의 `Slice`, `findPage`의 `Page`) +이 글은 Kotlin JDSL에서 nullable한 반환 타입을 허용하는 이유를 설명합니다. ## Nullable 반환 타입의 필요성 @@ -10,11 +11,11 @@ Kotlin JDSL이 nullable한 반환 타입을 지원하는 이유는 JPQL 쿼리 아래 표는 Kotlin JDSL을 사용할 때 nullable한 반환 타입이 발생할 수 있는 몇 가지 경우를 나타냅니다. -| 항목 | null 여부 | 이유 | -|----------------|---------|---------------------------------------------------------| -| DTO Projection | X | 모든 ROW에 대한 생성자 호출하기 때문에 객체가 생성되어 null을 허용하는 결과가 나오지 않음 | -| Column | O | null인 필드를 조회하는 경우 존재 | -| Entity | O | Left Join시 조인의 대상이 되는 Entity가 null인 경우 존재 | +| 항목 | null 여부 | 이유 | +|----------------|---------|-------------------------------------------------------------------------------------------------------| +| DTO Projection | X | 모든 ROW에 대한 생성자 호출하기 때문에 객체가 생성되어 null을 허용하는 결과가 나오지 않음
DTO의 필드가 null일 수는 있으나 DTO 객체가 null일 수는 없음 | +| Column | O | null인 필드를 조회하는 경우 존재 | +| Entity | O | Left Join시 조인의 대상이 되는 Entity가 null인 경우 존재 | 또 다른 예로 아래 코드는 Author 엔티티가 있지만, left join의 대상인 BookAuthor 엔티티는 null일 수 있는 상황을 보여줍니다. From 685c0e852c68fb468fbf56f8fa5fe520af0ebe0c Mon Sep 17 00:00:00 2001 From: progress0407 Date: Fri, 26 Apr 2024 00:19:03 +0900 Subject: [PATCH 3/3] docs: reflect second reviews --- ...turns-nullable-list-in-the-spring-support-module.md | 10 +++++----- ...turns-nullable-list-in-the-spring-support-module.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md b/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md index 6205da221..e261f11a1 100644 --- a/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md +++ b/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md @@ -11,11 +11,11 @@ The simplest example is when you look up a column or entity without using DTO Pr The table below shows some of the cases where nullable return types can occur when using the Kotlin JDSL. -| Item | Nullable or not | Reason | -|----------------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| DTO Projection | X | Calling the constructor for all ROWs did not result in the object being created to allow nulls.
Fields in DTO can be null, but DTO object cannot be null. | -| Column | O | Exists when looking up a field that is null. | -| Entity | O | Exists if the Entity being joined on Left Join is null. | +| Item | Nullable or not | Reason | +|----------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| DTO Projection | X | Because we're calling the constructor for all ROWs, the object is not created, resulting in a null-accepting result
Fields in DTO can be null, but DTO object cannot be null. | +| Column | O | Exists when looking up a field that is null. | +| Entity | O | Exists if the Entity being joined on Left Join is null. | As another example, the code below shows a situation where the Author entity exists, but the BookAuthor entity, the target of the left join, may be null. diff --git a/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md b/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md index 11a657dcc..b2a95cbca 100644 --- a/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md +++ b/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md @@ -11,11 +11,11 @@ Kotlin JDSL이 nullable한 반환 타입을 지원하는 이유는 JPQL 쿼리 아래 표는 Kotlin JDSL을 사용할 때 nullable한 반환 타입이 발생할 수 있는 몇 가지 경우를 나타냅니다. -| 항목 | null 여부 | 이유 | -|----------------|---------|-------------------------------------------------------------------------------------------------------| -| DTO Projection | X | 모든 ROW에 대한 생성자 호출하기 때문에 객체가 생성되어 null을 허용하는 결과가 나오지 않음
DTO의 필드가 null일 수는 있으나 DTO 객체가 null일 수는 없음 | -| Column | O | null인 필드를 조회하는 경우 존재 | -| Entity | O | Left Join시 조인의 대상이 되는 Entity가 null인 경우 존재 | +| 항목 | null 여부 | 이유 | +|----------------|---------|--------------------------------------------------------------------------------------------------------| +| DTO Projection | X | 모든 ROW에 대한 생성자를 호출하기 때문에 객체가 생성되어 null을 허용하는 결과가 나오지 않음
DTO의 필드가 null일 수는 있으나 DTO 객체가 null일 수는 없음 | +| Column | O | null인 필드를 조회하는 경우 존재 | +| Entity | O | Left Join시 조인의 대상이 되는 Entity가 null인 경우 존재 | 또 다른 예로 아래 코드는 Author 엔티티가 있지만, left join의 대상인 BookAuthor 엔티티는 null일 수 있는 상황을 보여줍니다.