After reading Spring's docs at https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries.update , I wrote this Repository method:
@Repository
interface TokenRepo: MongoRepository<TokenModel, String> {
@Query("{ authorizationState: ?0 }")
@Update("{ authorizationState: ?0, authorizationCode: ?1 }")
fun updateCode(state: String, code: String): Int
}
Then I use it like this:
@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")
}
But this fails when reading back from the database, because almost all fields were set to 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)
How am I supposed to use @Update
? Or is it only intended for things like $inc
and $push
? The docs is actually quite brief on this topic. I'm relatively new to MongoDB.
All right that was quick. It was me being new into MongoDB.
Spring Data MongoDB is really just a thin layer, so one needs to follow the MongoDB query language to the extent where update happens through $set { ... }
.
So the method is supposed to be like this:
@Query("{ authorizationState: ?0 }")
@Update("{ '\$set': { authorizationCode: ?1 } }")
fun updateCode(state: String, code: String): Int