Comments 13
А насколько хорошо data class работает в качестве entity? Есть подозрение, что неизменяемый id поломает вам работу при createTask, если конечно Вы не генерируете id на вызывающей стороне.
Но с общей мыслью согласен - котлин очень сахарный относительно джавы, да и со спрингом дружит отлично, так что всех агитирую новые проекты начинать на котлине)
Разве id как-то меняется при создании? Там же внутри просто распарс на sql запрос идет, а возвращаться вряд ли будет тот же объект
UPD: возможно тут имелось ввиду, что Long без "?", не увидел этого
id non nullable поле и генерируется на вызывающей стороне.
Возвращаться будет объект, который создали.
ID может меняться при создании. Когда с условного фронта приходит набор полей для сохранения в БД (в виде объекта Task), то никаким ид (читай первичный ключ из БД) там не пахнет. И этот ID генерируется в БД, а затем присваивается в поле Task.id.
Ну и если посмотреть, как работает JPA и Hibernate под капотом, то там генерация запроса и основывается на наличии\отсутствии id поля. Если поля нет - то генерируется insert, иначе генерируется update.
можно сделать так
@Id @GeneratedValue(strategy = GenerationType.UUID)
val id: UUID?
Тогда в запросе передавать id не надо. Генерироваться будет автоматически.
Спасибо. Дополнил.
Сразу бросился в глаза data class для Entity, который категорически не рекомендуют использовать, есть проблемы с избыточностью запросов для lazy полей, которые участвуют в hashCode, equals и toString. ID поле как val id: *? (nullable) нормально работает, на сколько помню
Для вводной статьи рекомендовал бы на это обратить внимание, и как будто бы убрать data class из нее
Зачем мешать Optional и исключения? Почему нельзя вернуть None и обработать в дальнейшем? Optional же как раз подразумевает наличие или отсутствие значения нужного типа. Ну а если нужно вернуть либо значение, либо исключение, почему нельзя использовать, например, Either из Arrow?
Согласен, можно и так.
можно переписать таким образом
fun getTaskById(taskId: Long): Task = taskRepository.findById(taskId)
.orElseThrow { TaskNotFoundException(HttpStatus.NOT_FOUND, "Задача с $taskId не найдена") }
А ещё лучше так
fun getTaskById(taskId: Long): Task = taskRepository.findByIdOrNull(taskId)
?: throw TaskNotFoundException(HttpStatus.NOT_FOUND, "Задача с $taskId не найдена")
Благо в Spring есть Kotlin extension findByIdOrNull
для CrudRepository
а работа с Optional
в котлин коде считается моветоном :)
P.S. Ещё DELETE по спецификации REST должен быть идемпотентный, так что нет смысла проверять на наличие в репозитории, правильнее будет просто молча вызывать deleteById
А DTO нет, как же без DTO?
Или в Котлине оно не нужно?
Разработка REST API с использованием Kotlin и Spring Boot: сочетание простоты и мощи