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)
Спасибо Джордано, который показал мне способ сделать функцию более краткой.