Skip to content
Advertisement

Ktorm entities as springboot controller parameters

I’m trying to use Ktorm in my new springboot application, and get myself into problem when trying to use Ktorm entities interfaces as springboot controller parameters.

The entity and Controller look like this:

// Controller definition
@RestController
class TaskController() {

    @PostMapping
    fun addTask(
        @RequestBody task: Task
    ): Long {
        // ... do something with `task`
    }
}

// Entity definition (unncessary properties are omitted)
interface Task : Entity<Task> {

    var id: Long
    var title: String
    var content: String

    companion object : Entity.Factory<Task>()
}

I got this exception once calling function addTask():

[HttpMessageConversionException] Type definition error: [simple type, class website.smsqo.entity.Task]; nested exception is:

[com.fasterxml.jackson.databind.exc.InvalidDefinitionException] Cannot construct instance of website.smsqo.entity.Task (no Creators, like default constructor, exist):

abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type informationn at [Source: (PushbackInputStream); line: 1, column: 1]” }

(Paramter task is posted from front-end by RequestBody)

I think maybe the reason is that, as an interface, springboot can’t find a proper way to initialize Task. However, refactoring it into this is surely not an elegant solution:

@RestController
class TaskController() {

    @PostMapping
    fun addTask(
        id: Long, title: String, content: String // even more fields...
    ): Long {
        val task = Task {
            this.id = id
            this.title = title
            this.content = content
        }
        // ... do something with `task`
    }
}

Any better solution proposed? Thanks for your reply in advance!

Advertisement

Answer

Well, it turns out that solution was noted explicitly in documents provided by Ktorm:

// extracted from org.ktorm.entity.Entity

/*
 * Besides of JDK serialization, the ktorm-jackson module also supports serializing entities in JSON format. This
 * module provides an extension for Jackson, the famous JSON framework in Java word. It supports serializing entity
 * objects into JSON format and parsing JSONs as entity objects. More details can be found in its documentation.
 */

Implementing org.ktorm:ktorm-jackson:3.4.1 brings us a Jackson Module, named KtormModule in package org.ktorm.jackson. What we need to do next is applying the module to our springboot application as in class annotated by @Configuration:

@Configuration
class KtormConfig {
    @Bean
    fun ktormJacksonModule(): Module = KtormModule()

    // ... and other configurations if you like
}

And that’s it. Such KtormModule will be discovered and applied by jackson on springboot application launches, after which there’s no more problem encoding and decoding between json and Ktorm Entities.

Advertisement