Spring NamedParameterJdbcTemplate 无法使用 Kotlin 插入 NULL

Spring NamedParameterJdbcTemplate Cannot Insert NULL using Kotlin

我将 Kotlin 与 Spring Boot 2 一起使用。我只是用一个可能为 null 也可能不为 null 的字段做一个简单的插入。但是,在 Kotlin 中,使用 MapSqlParameterSource 似乎不可能,因为 .addValue 方法不接受 null 或可为 null 的类型。这是相当不寻常的,因为 insert 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 没有提供创建事物地图的优雅方式。因为我们可以在 Kotlin 中使用 mapOf(),所以我们可能根本不需要 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)。

我猜这是在 this commit 中无意中引入的错误。但同样,我们有 mapOf(),可能不需要这个。