Я использую Kotlin с Spring Boot 2. Я просто делаю простую вставку с полем, которое может быть или не быть нулевым. Однако в Kotlin это невозможно с использованием MapSqlParameterSource, потому что методы .addValue не принимают типы, допускающие значение NULL или допускающие значение NULL. Это довольно необычно, потому что вставка NULL может быть допустимым вариантом использования. В прошлом это было очень просто и легко с Java и Spring Boot. Есть ли способ обойти это, я действительно не хочу прыгать через обручи, чтобы сделать что-то простое и прямолинейное.
@Transactional
fun saveSubmittedAnswer(answer: AnswerSubmissionRequest) {
val query = """INSERT INTO dab.SubmittedAnswer (Id, QuestionId, Answer, SurveyId, ParentQuestionId, TimeTaken
| VALUES (:id, :questionId, :answer, :surveyId, :parentQuestionId, :timeTaken)
""".trimMargin()
answer.answers.forEach { ans ->
val params: MapSqlParameterSource = MapSqlParameterSource()
.addValue("id", UUID.randomUUID())
.addValue("questionId", ans.questionId)
.addValue("answer", ans.answer)
.addValue("surveyId", answer.surveyId)
//.addValue("parentQuestionId", ans.parentId)
.addValue("timeTaken", ans.timeTaken)
this.jdbcTemplate.update(query, params)
}
}
Для всех методов требуется тип, не допускающий значения NULL.
Причина, по которой существует MapSqlParameterSource, заключается в том, что Java не предоставляет элегантного способа создания карт вещей. Поскольку мы можем использовать mapOf() в Kotlin, нам, вероятно, вообще не нужен MapSqlParameterSource.
Если бы это был я, я бы предпочел просто использовать mapOf() и полностью избегать MapSqlParameterSource:
val params = mapOf(
"id" to UUID.randomUUID(),
"questionId" to ans.questionId,
"answer" to ans.answer,
"surveyId" to answer.surveyId,
"parentQuestionId" to ans.parentId,
"timeTaken" to ans.timeTaken
)
jdbcTemplate.update(query, params)
Однако я согласен, что это похоже на недосмотр API. Вероятно, он был введен, когда были добавлены аннотации обнуляемости, чтобы облегчить жизнь пользователям Kotlin.
Мне показалось, что это скомпилировано, но я попробовал это только в IDE и не запускал:
MapSqlParameterSource()
.addValue("notNullable", myObject.notNulableValue)
.addValues(mapOf("nullable" to myObject.nullableValue))
Это работает, потому что функция addValues принимает Map<String, ?> (что интересно, @Nullable).
Я предполагаю, что это ошибка, случайно введенная в это коммит. Но опять же, у нас есть mapOf(), и он, наверное, не нужен.
Это отличный момент для использования карты, и это, вероятно, больше похоже на Kotlin. Однако я согласен с тем, что API MapSqlParameterSource для Kotlin является ошибкой. Интересно, было ли об этом заявлено?
@greyfox. Сейчас это исправлено: github.com/spring-projects/spring-framework/commit/…
Угу. Я согласен с вами. NULL является допустимой возможной ситуацией и условием, но новая хипстерская тенденция состоит в том, что ничто никогда не должно возвращать NULL. Неважно, сколько лишнего кода шаблона, который создает для всякой ерунды, вроде необязательного класса в Java и любого эквивалента Kotlin.