Spring NamedParameterJdbcTemplate не может вставить NULL с помощью Kotlin

Я использую 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.

Spring NamedParameterJdbcTemplate не может вставить NULL с помощью Kotlin

Угу. Я согласен с вами. NULL является допустимой возможной ситуацией и условием, но новая хипстерская тенденция состоит в том, что ничто никогда не должно возвращать NULL. Неважно, сколько лишнего кода шаблона, который создает для всякой ерунды, вроде необязательного класса в Java и любого эквивалента Kotlin.

BrianC 10.04.2018 23:38
4
1
1 076
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина, по которой существует 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 11.04.2018 15:35

@greyfox. Сейчас это исправлено: github.com/spring-projects/spring-framework/commit/…

Florian Tavares 18.10.2018 10:38

Другие вопросы по теме