Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exposed: How to parse JSON into an Entity class

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.

like image 366
Ilia Choly Avatar asked Jan 08 '18 21:01

Ilia Choly


1 Answers

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

like image 133
msrd0 Avatar answered Nov 18 '22 19:11

msrd0