J'écris une application Spring Boot avec Spring Data JPA et Kotlin, et j'ai remarqué que dans CrudRepository
, il y a la méthode suivante:
Optional<T> findById(ID id);
J'utilise Kotlin, cependant, qui a des manières beaucoup plus fluides de gérer les valeurs nulles que Optional
. Est-ce que quelqu'un sait comment je convertirais cette méthode pour fonctionner comme ça?
fun findById(id: ID): T?
Lorsque j'étends Repository
lui-même et crée un dépôt avec cette signature, j'obtiens l'erreur:
Java.lang.ClassCastException: Java.util.Optional cannot be cast to com.books.Book
À partir de Spring Data Lovelace SR4/Spring Boot 2.1.2, une extension CrudRepository.findByIdOrNull(id: ID): T? = findById(id).orElse(null)
Kotlin fournit désormais un moyen de récupérer des entités nullables dans Spring Data.
Si, pour des raisons de performances, vous souhaitez éviter l'utilisation du wrapper Optional<T>
, Sachez que vous avez également la possibilité de créer une interface personnalisée avec une fonction findFooById(id: ID): T?
. L'exécution des requêtes est spécifique au magasin, mais la plupart utilisent des valeurs annulables en interne et éviteront le coût du wrapper Optional<T>
. Notez que cette surcharge doit être négligeable dans la plupart des cas d'utilisation, il est donc recommandé d'utiliser l'extension intégrée.
Voir DATACMNS-1346 pour plus de détails.
Mise à jour 12/2018:
Un changement à venir dans le framework Spring Data rendra cette réponse obsolète. La mise à jour fait essentiellement la même chose que cette réponse: définir une fonction d'extension appropriée. Veuillez consulter réponse de Sébastien Deleuze pour plus de détails.
Réponse originale:
Comme vous l'avez correctement indiqué, vous n'avez pas besoin de Optional
dans Kotlin, car la gestion de la nullité de manière concise est une fonctionnalité de langage intégré.
Vous pouvez créer votre propre fonction d'extension pour obtenir le comportement souhaité:
fun <T, ID> CrudRepository<T, ID>.findOne(id: ID): T? = findById(id).orElse(null)
et utilisez-le comme ceci:
val fruit: Fruit? = fruitRepository.findOne(id)
Merci à Giordano qui m'a montré un moyen de rendre la fonction plus concise.