Kotlin serialization incorrect data spring server side


#1

Using Kotlin serialization with a multiplatform project. Data looks good till it is caught by the rest controller. When the data comes back to the server all of the data that is part of the DataTransportObject abstract class is the default data. When I debug it on the JS side before sending to rest service it looks perfect

here is my abstract class:

@Serializable
abstract class DataTransportObject(
    open var id: Int = 0,
    open var dateCreated: DateTime? = DateTime(),
    open var dateUpdated: DateTime?  = DateTime()
)

here is the class using it

@Serializable
data class BlogPostDto (override var id:Int, override var dateCreated: DateTime?, override var dateUpdated: DateTime?): DataTransportObject( id, dateCreated,dateUpdated){
    var title:String = ""
    var description:String = ""
    var content:String = ""
    var secRoleDetailAuthor:DtoMin = DtoMin(0,DateTime(),DateTime())
}

@PostMapping("/{id}")
fun update(@PathVariable id: Long, @RequestBody dto: CommentDto): CommentDto {
    var adjustedDto = dto
    dto.id = id.toInt()
    val response: UpdateComment.Response  = updateComment.update(UpdateComment.Request(adjustedDto))
    when(response){
        is UpdateComment.Response.Success -> return response.dto
        is UpdateComment.Response.Failure -> throw RestUpdateFailureException(clazz = "Comment", msg = response.errMsg)
    }
}

client side when i console out the dto being sent id/dateCreated/dateUpdated is correct. On the server side the id, dateCreated and dateUpdated are all the default values.

Any ideas?


#2

It is hard to determine without a complete example. I am not able to reproduce the issue myself. I do, however, notice a few problems with your code which may be relevant.

Spring does not use kotlinx.serialization by default. Instead it uses Jackson for serialization

Your DTO hierarchy is a bit odd:

  1. Why do you define non-abstract properties in your base class and then override it with new properties in your subclasses? The result is that at runtime you will have two backing fields for each property (one from the base class and one from the subclass)
  2. You are defining your subclass as a data class, but only define some of the properties in the constructor. Remember that the compiler will only include the properties defined in the primary constructor in the auto-generated methods (hashcode, equals, toString etc.)

#3

TY Varia,

i have tried it a bunch of ways, this was just the latest… I will try and get rid of the jackson serializtion this week. Will Spring use the kotlinx if it is put in its place via build.gradle?


#4

I set up a test project that is simple at https://github.com/ideaBlender/multiplatformsandbox

the dto on the controller side always comes in with default values, not the correct values seen client side…


#5

You where 100% right, i cleaned up the Abstract class usage and the data looks wonderful