diff --git a/docs/en/faq/why-is-there-a-support-module-that-only-has-a-nullable-return-type.md b/docs/en/faq/why-is-there-a-support-module-that-only-has-a-nullable-return-type.md new file mode 100644 index 000000000..9d32db28f --- /dev/null +++ b/docs/en/faq/why-is-there-a-support-module-that-only-has-a-nullable-return-type.md @@ -0,0 +1,29 @@ +# Why is there a support module that only has a nullable return type? + +You may have noticed that the methods provided by Kotlin JDSL through some support module all have only nullable return types. +Kotlin JDSL cannot infer whether the return type of query is non-null or nullable, because it doesn't know whether the result of a Join in the query is nullable or not. +Here are some cases where this results in a nullable return. + +| Return Type | Comment | +|-------------|--------------------------------------------------------------------------------------| +| Column | It can return null when the column's definition is nullable. | +| Entity | It can return null when the entity is joined in a nullable way, such as a left join. | + +For example, the following returns a nullable entity due to a left join. + +```kotlin +val query = jpql { + select( + path(BookAuthor), + ).from( + entity(Author::class), + leftJoin(BookAuthor::class).on(path(Author::authorId).equal(path(BookAuthor::authorId))) + ) +} +``` + +Kotlin JDSL could have provided methods with nullable and non-null return types separately, but it didn't, because this could be confusing for users. +For example, JPQL uses nullable return types by default, so it doesn't have a naming convention for non-null return types. +If Kotlin JDSL introduced its own naming convention, users might have questions about the internal implementation. +For example, does a method filter out nullable values and return them, or does it throw an exception if it contains a null? +Because Kotlin JDSL doesn't want users to have an additional learning burden while using the library, it hasn't defined its own methods. 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 deleted file mode 100644 index e261f11a1..000000000 --- a/docs/en/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md +++ /dev/null @@ -1,40 +0,0 @@ -# Why does Kotlin JDSL allow nullable return types? - -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? - -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 | 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. - -```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-is-there-a-support-module-that-only-has-a-nullable-return-type.md b/docs/ko/faq/why-is-there-a-support-module-that-only-has-a-nullable-return-type.md new file mode 100644 index 000000000..b10c21f1b --- /dev/null +++ b/docs/ko/faq/why-is-there-a-support-module-that-only-has-a-nullable-return-type.md @@ -0,0 +1,29 @@ +# 왜 Kotlin JDSL은 Nullable한 반환 타입을 허용하나요? + +아마도 Kotlin JDSL의 일부 support 모듈이 제공하는 메소드들이 모두 nullable 반환 타입만 가진 것에 의문을 가지실 수 있습니다. +쿼리에 있는 Join 결과가 nullable인지 아닌지 알 수 없기 때문에 Kotlin JDSL은 쿼리의 반환 타입이 non-null인지 nulalble인지 추론할 수 없습니다. +다음은 nullable 타입이 반환되는 몇가지 케이스들입니다. + +| Return Type | Comment | +|-------------|-------------------------------------------------------------------| +| Column | Column 정의가 nullable일 경우 null을 반환할 수 있습니다. | +| Entity | Left Join과 같이 entity가 nullable한 방식으로 Join되었을 경우 null을 반환할 수 있습니다. | + +예를 들어서 다음은 Left Join으로 인해 nullable한 entity를 반환하는 경우입니다. + +```kotlin +val query = jpql { + select( + path(BookAuthor), + ).from( + entity(Author::class), + leftJoin(BookAuthor::class).on(path(Author::authorId).equal(path(BookAuthor::authorId))), + ) +} +``` + +Kotlin JDSL은 non-null한 반환 타입과 nullable한 반환 타입을 구분해서 별도로 메소드를 제공할 수 있었지만 사용자에게 혼란을 줄 수 있기 때문에 그렇게 하지 않았습니다. +예를 들어 JPQL은 기본적으로 nullable한 반환 타입을 사용하므로 non-null 반환 타입에 대한 네이밍 컨벤션이 없습니다. +Kotlin JDSL이 네이밍 컨벤션을 도입할 경우 사용자는 내부 구현에 대해 의문을 가질 수 있습니다. +예를 들어 메소드가 null을 필터링해서 반환하는지 null이 포함된 경우 예외를 던지는지 헷갈릴 수 있습니다. +Kotlin JDSL은 사용자가 라이브러리를 사용할 때 추가적인 학습을 하는 것을 바라지 않기 때문에 Kotlin JDSL은 자체 메소드를 정의하지 않았습니다. 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 deleted file mode 100644 index b2a95cbca..000000000 --- a/docs/ko/faq/why-kotlin-jdsl-returns-nullable-list-in-the-spring-support-module.md +++ /dev/null @@ -1,40 +0,0 @@ -# 왜 Kotlin JDSL은 Nullable한 반환 타입을 허용하나요? - -Kotlin JDSL을 사용하면 Type Safe하게 쿼리를 작성할 수 있게 도와주지만 -다건의 데이터를 반환할 때 non-null한 데이터 또한 null을 허용하는지 궁금증을 가질 수 있습니다. (예를 들어 `findSlice`의 `Slice`, `findPage`의 `Page`) -이 글은 Kotlin JDSL에서 nullable한 반환 타입을 허용하는 이유를 설명합니다. - -## Nullable 반환 타입의 필요성 - -Kotlin JDSL이 nullable한 반환 타입을 지원하는 이유는 JPQL 쿼리의 작성 방법에 따라 반환되는 리스트 항목 중 null 값이 포함될 수 있기 때문입니다. -가장 간단한 예로는 DTO Projection을 사용하지 않고, column이나 entity를 조회할 때를 들 수 있습니다. - -아래 표는 Kotlin JDSL을 사용할 때 nullable한 반환 타입이 발생할 수 있는 몇 가지 경우를 나타냅니다. - -| 항목 | null 여부 | 이유 | -|----------------|---------|--------------------------------------------------------------------------------------------------------| -| DTO Projection | X | 모든 ROW에 대한 생성자를 호출하기 때문에 객체가 생성되어 null을 허용하는 결과가 나오지 않음
DTO의 필드가 null일 수는 있으나 DTO 객체가 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 지식을 기반으로 활용할 수 있게 합니다.