'Mapping @Json property with JDBI

According to JDBI document https://jdbi.org/#_jackson_2, it seems that it's quite straight forward to have a json property of your object model, however I've tried the following and it ran into many issues.

DB: Postgres with a column type of Jsonb

class Event {
    private String name;
    @Json
    private EventProperty jsonProperty;
    ...
}

Datasource has been configured with

    @Bean
    public Jdbi jdbi(TransactionAwareDataSourceProxy eventStoreTxAwareDataSourceProxy) {
        Jdbi jdbi = Jdbi.create(eventStoreTxAwareDataSourceProxy);
        jdbi.installPlugin(new PostgresPlugin());
        jdbi.installPlugin(new Jackson2Plugin());
    }

SQL for binding list of insertion

INSERT INTO event (name, json_property)
VALUES (
        :name,
        :jsonProperty)

When running the code to insert, the following error occurred:

org.jdbi.v3.core.statement.UnableToCreateStatementException: no argument factory for type com.EventProperty [statement:"INSERT INTO event (...]

If I created EventPropertyArgumentFactory and using Jackson ObjectMapper and writeValueAsString then I can save it to DB. However, when retrieving it back from DB by

 try (Handle handle = jdbi.open()) {
    EventDao dao = handle.attach(EventDao.class);
    return dao.findByName(name);
}

throws the following errors

java.lang.ClassCastException: Cannot cast org.postgresql.util.PGobject to com.EventProperty

I thought all I needed to do is declare the field annotated with @Json, the DB column has to be json/jsonb type and install the plugins, but seems like this is not the case?

Anyone has tried this successfully, without having to define custom row mapper and argument factory implementation?

Thanks



Solution 1:[1]

Not sure if you've figured this out by now but I just ran into this same issue and finally figured it out.

Basically, you just have to add the annotation on the getter or setter of the class, not the top-level field.

class Event {
    private String name;
    private EventProperty jsonProperty;
    ...

    @Json
    public getEventProperty() {
        return jsonProperty;
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 D. Mallon