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()
,可能不需要这个。
我将 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()
,可能不需要这个。