Spring Данные JPA Как использовать нулевые значения Kotlin вместо необязательного

Я пишу приложение Spring Boot с Spring данными JPA и Kotlin, и я заметил, что в CrudRepository существует следующий метод:

Optional<T> findById(ID id);

Я использую Kotlin, тем не менее, у которого есть гораздо более быстрые способы иметь дело с нулями, чем Optional. Кто-нибудь знает, как я буду преобразовывать этот метод для работы следующим образом?

fun findById(id: ID): T?

Когда я расширяю Repository и создаю репо с этой сигнатурой, я получаю ошибку:

java.lang.ClassCastException: java.util.Optional cannot be cast to com.books.Book

Ответ 1

Начиная с Spring Data Lovelace SR4/Spring Boot 2.1.2, CrudRepository.findByIdOrNull(id: ID): T? = findById(id).orElse(null) CrudRepository.findByIdOrNull(id: ID): T? = findById(id).orElse(null) Расширение Kotlin теперь предоставляет CrudRepository.findByIdOrNull(id: ID): T? = findById(id).orElse(null) способ извлечения обнуляемых объектов в Spring Data.

Если по соображениям производительности вы хотели бы избежать использования Optional<T> оболочки Optional<T>, имейте в виду, что у вас также есть возможность создать пользовательский интерфейс с помощью findFooById(id: ID): T? функция. Выполнение запроса зависит от хранилища, но большинство использует внутренние значения, допускающие значения NULL, и позволит избежать затрат на Optional<T> оболочку Optional<T>. Обратите внимание, что эти издержки должны быть незначительными для большинства случаев использования, поэтому рекомендуется использовать встроенное расширение.

См. DATACMNS-1346 для более подробной информации.

Ответ 2

Обновление 12/2018:

Предстоящее изменение в среде Spring Data сделает этот ответ устаревшим. Обновление в основном делает то же самое, что и этот ответ: определить соответствующую функцию расширения. Пожалуйста, смотрите ответ Себастьяна Делеза для получения более подробной информации.

Оригинальный ответ:

Как вы правильно сказали, вам не нужен Optional в Kotlin, потому что краткая обработка обнуляемости - это встроенная функция языка.

Вы можете создать свою собственную функцию расширения для достижения желаемого поведения:

fun <T, ID> CrudRepository<T, ID>.findOne(id: ID): T? = findById(id).orElse(null)

и используйте это так:

val fruit: Fruit? = fruitRepository.findOne(id)

Спасибо Джордано, который показал мне способ сделать функцию более краткой.