Reputation: 567
Ideally using Jackson on the Java side of things. I have tried the obvious solution:
public class JsonObjectConverter implements Converter<Object, ObjectNode> {
private final ObjectMapper mapper = new ObjectMapper();
@Override public ObjectNode from(Object dbo) {
try {
return dbo != null ? mapper.readValue((String) dbo, ObjectNode.class) : null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override public Object to(ObjectNode uo) {
try {
return uo != null ? mapper.writeValueAsString(uo) : null;
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@Override public Class<Object> fromType() {
return Object.class;
}
@Override public Class<ObjectNode> toType() {
return ObjectNode.class;
}
}
But if I try to use this I get errors like the following:
org.jooq.exception.DataAccessException: SQL [insert into "public"."my_table" ("id", "stuff") values (?, ?)]; ERROR: column "stuff" is of type json but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
However because of jOOQs enforced type safety (which is great, BTW) I can't just add a .cast(String.class)
and be done. So, do I need to do something else in the converter, or should the code be called in a different way? I'm currently doing this:
Long id = ...
ObjectNode stuff = ...
create.insertInto(MY_TABLE)
.set(MY_TABLE.ID, id)
.set(MY_TABLE.STUFF, stuff)
.execute();
and am using updatable records in other places in my code.
Upvotes: 2
Views: 3385
Reputation: 221275
You probably won't get the JSON data type 100% correct with a Converter
only. Ideally, you should use a jOOQ 3.5 org.jooq.Binding
implementation, which is documented here:
The code generator can be configured to use your custom Binding
(instead or in addition to Converters
) directly on your database columns. The Binding
will then take care of all necessary interaction on a JDBC level.
Upvotes: 0
Reputation: 567
Yes, it is, but you need to use Postgres specific API. In the code above you need to replace the from/to methods with the following:
@Override
public ObjectNode from(Object databaseObject) {
if (databaseObject == null) { return null; }
try {
PGobject dbo = (PGobject) databaseObject;
return mapper.readValue(dbo.getValue(), ObjectNode.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public Object to(ObjectNode userObject) {
if (userObject == null) { return null; }
try {
PGobject dbo = new PGobject();
dbo.setType("json");
dbo.setValue(mapper.writeValueAsString(userObject));
return dbo;
} catch (JsonProcessingException|SQLException e) {
throw new RuntimeException(e);
}
}
Upvotes: 4