1

Question:

In my MySQL database, I have an info column of JSON type: info json DEFAULT NULL,

I wrote a simple converter as follows and registered it with the code generator:

class JsonMapConverter : AbstractConverter<JSON, Map<*, *>>(JSON::class.java, Map::class.java) {
    override fun from(databaseObject: JSON?): Map<*, *> =
        jacksonObjectMapper().readValue(databaseObject.toString(), Map::class.java)

    override fun to(userObject: Map<*, *>): JSON =
        JSON.json(jacksonObjectMapper().writeValueAsString(userObject))
}

Insert and update work fine with this converter. However, now I want to update the JSON field with MySQL's JSON_MERGE_PATCH instead of simply replacing the entire JSON object on every update.

I thought of jOOQ data binding, but after a while of researching, my head started to spin because I am very unfamiliar with JDBC.

Is it actually possible to achieve what I want with jOOQ data binding?

Versions:

  • jOOQ: 3.14.4
  • Kotlin: 1.4.10
  • Database: MySQL 5.7.32
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509

1 Answers1

1

Whenever jOOQ is missing support for a vendor specific feature, use plain SQL templating.

fun jsonMergePatch(vararg fields: Field<Map<*, *>>): Field<Map<*, *>> = DSL.field(
    "json_merge_patch({0})", 
    SQLDataType.JSON.asConvertedDataType(JsonMapConverter()),
    DSL.list(*fields)
);

Now you can use it as if it were an ordinary jOOQ function.

Alternatively, if you don't want to link this functionality to a specific converter, do this:

fun <T> jsonMergePatch(vararg fields: Field<T>): Field<T> = DSL.field(
    "json_merge_patch({0})", 
    fields[0].getDataType(),
    DSL.list(*fields)
);
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • Thank you for your reply! This works for me. Just a quick follow-up question, are you recommending against using binding in this case, or it's just not possible to achieve this feature with binding? Assuming I want to make this update behavior universal for all JSON objects in my DB, – Thanh Tùng Bùi Apr 01 '21 at 03:06
  • By "binding" you mean an `org.jooq.Binding`? You didn't use one in your question, so I didn't use one in my answer... I'll make my answer a bit more generic – Lukas Eder Apr 01 '21 at 09:26
  • Thank you! This generic solution helps a lot. – Thanh Tùng Bùi Apr 09 '21 at 06:13