После прочтения документации Spring по адресу https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries.update, Я написал этот метод репозитория:
@Repository
interface TokenRepo: MongoRepository<TokenModel, String> {
@Query("{ authorizationState: ?0 }")
@Update("{ authorizationState: ?0, authorizationCode: ?1 }")
fun updateCode(state: String, code: String): Int
}
Затем я использую это так:
@Test fun testUpdate() {
val token = TestTokenModels().makeToken()
val tokenSaved = tokenRepo.save(token)
assertThat(tokenSaved).isNotNull.isEqualTo(token)
assertThat(tokenSaved.requestTimestampMs).isNotNull()
assertThat(tokenRepo.findByState(token.authorizationState)).isNotNull.isEqualTo(token)
tokenRepo.updateCode(token.authorizationState, "someCode")
val tokenUpdated = tokenRepo.findByState(token.authorizationState) // FAILS!
assertThat(tokenUpdated).isNotNull
assertThat(tokenUpdated!!.authorizationCode).isNotNull.isEqualTo("someCode")
}
Но это не удается при обратном чтении из базы данных, потому что почти все поля были установлены в null:
org.springframework.data.mapping.model.MappingInstantiationException:
Failed to instantiate com.tracker.bl.token.TokenModel using constructor
fun `<init>`(kotlin.String, com.tracker.bl.token.TokenModel.Status, kotlin.String, kotlin.String, kotlin.String, kotlin.Long, kotlin.String, kotlin.String, kotlin.String?, kotlin.String?, com.tracker.rest.Oauth2TokenType, kotlin.String?, kotlin.String?, kotlin.Long?, java.time.ZonedDateTime, kotlin.String?): com.tracker.bl.token.TokenModel with arguments 637e4686ae781b603ac77c12,null,null,null,null,null,null,tokenFlowStateVC8g80BT,null,null,null,null,null,null,null,null,65026,null
at org.springframework.data.mapping.model.
KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter
.createInstance(KotlinClassGeneratingEntityInstantiator.java:215)
Как я должен использовать @Update
? Или он предназначен только для таких вещей, как $inc
и $push
? Документы на самом деле довольно кратки по этой теме. Я относительно новичок в MongoDB.
Ладно, это было быстро. Это я был новичком в MongoDB.
Spring Data MongoDB — это всего лишь тонкий слой, поэтому нужно следовать языку запросов MongoDB до такой степени, что обновление происходит через $set { ... }
.
Итак, метод должен быть таким:
@Query("{ authorizationState: ?0 }")
@Update("{ '\$set': { authorizationCode: ?1 } }")
fun updateCode(state: String, code: String): Int