8

I have the following user table object & entity class:

object UserTable : IntIdTable() {
    val name = varchar("name", 256)
}

class User(id: EntityID<Int>): IntEntity(id) {
    companion object : IntEntityClass<User>(UserTable)
    val name by UserTable.name
}

Is there a way to use Gson (or some other library) to parse JSON into a User instance, and then insert it? From what I can tell, it seems like I'll have to create an intermediate UserData data class and then manually copy the fields over.

data class UserData {
  var id: Int?
  var name: String?
}

fun main() {
  val data = Gson().fromJson<UserData>("...", UserData::class.java)
  val user = User.new {
    name = data.name
  }
}

It's not that bad in this contrived example, but I'm wondering if there's a dry'er approach.

4

1 回答 1

6

Exposed does not allow creating DAO objects by yourself because you always need to pass an EntityID to the constructor. However, Jackson supports reading an existing object. So, you can write something like this:

transaction {
    User.new {
        mapper.readerForUpdating(this).readValue(json)
    }
}

To make sure that Jackson and Exposed don't interfere, you'll have to create your mapper like this:

val mapper by lazy {
    val mapper = jacksonObjectMapper()
    mapper.setAnnotationIntrospector(object : JacksonAnnotationIntrospector() {
        override fun hasIgnoreMarker(m : AnnotatedMember)
            =  (m.getDeclaringClass() == IntEntity::class.java)
            || (m.getDeclaringClass() == Entity::class.java)
            || super.hasIgnoreMarker(m)
    })
    mapper
}

Also note that you cannot put @JsonProperty annotation on delegated properties but you must use @get:JsonProperty.

In order to use Jackson, add the following to your build.gradle file (if you are not using gradle, you'll have to adapt that code to your build system):

compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.0"

Here is a fully working example: https://gist.github.com/msrd0/1d8d3d76de4010cc72868d8a36f0560a

于 2018-01-09T06:08:03.950 回答