I'm trying to write a JSON column to MySQL using JOOQ and Jackson but I'm not sure why it isn't serialized as JSON but as a toString representation.
Here is a table for which I generate JOOQ definitions:
create table JsonPayload
(
name varchar(127) primary key,
rules JSON not null,
defaultValue tinyint(1) default 0 not null
);
This are the classes I'd like to bind my model.
data class RuleTest(val name: String, val test: Boolean)
data class Rule(val name: String, val test: Boolean, val rule: RuleTest)
data class JsonPayload(val name: String, val rules: List<Rule>, val defaultValue: Boolean)
Insertion code:
dsl.insertInto(JSONPAYLOAD)
.set(dsl.newRecord(
JSONPAYLOAD,
JsonPayload(
"Test",
listOf(Rule("rule1", false, RuleTest("rule1", false)),
Rule("rule2", true, RuleTest("rule1", false))),
true
)
))
.execute()
It serializes and deserializes fine, however it doesn't write correct JSON to MySQL:
mysql> select * from JsonPayload;
+------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------+
| name | rules | defaultValue |
+------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------+
| Test | ["Rule(name=rule1, test=false, rule=RuleTest(name=rule1, test=false))", "Rule(name=rule2, test=true, rule=RuleTest(name=rule1, test=false))"] | 1 |
+------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------+
This is the demo project I created to demonstrate this behaviour https://github.com/v1ctor/jooq-json-demo
Can you please help me to understand how to write correct Json to MySQL?
That's an interesting feature idea, which isn't supported yet by the DefaultRecordUnmapper
implementation in jOOQ. I've created feature requests for this:
DefaultRecordUnmapper
Currently, Jackson can only be used for mapping JSON
and JSONB
to your own data structures when reading from the database. Not when writing to the database. But there isn't any reason why the inverse logic shouldn't be available as well.
In the meantime, you have to implement a data type Converter<JSON, List<Rule>>
(or a Binding
, if you need more power) and attach that to your generated code, see:
The benefit of using a Converter
is that you now get type safety whenever you read/write to this column. Alternatively, implement a RecordUnmapperProvider
to globally override the default behaviour.