user10993231
user10993231

Reputation: 111

how can I use spring to deserialize a postgres jsonb column to a list of objects?

I have a list of domain objects being saved to a postgres jsonb column (hibernate/jackson). The save works as expected but I get a mapping exception when deserializing. It looks like jackson is trying to deserialize to the domain object rather than a list of domain objects as specified by the type.

This is the field. It gets serialized and saved properly, as a list of stores.

@TypeDef(name = "stores",
    typeClass = JSONBUserType.class,
    parameters = {
        @Parameter(name = JSONBUserType.CLASS,
            value = "com.project.domain.metadata.Store")
    }
)


    @Column(name = "stores")
    @Type(type = "stores")
    private List<Store> stores;

This is the error I get when fetching the saved info. It looks like jackson is trying to deserialize it into a Store object rather than List<Store>.

org.springframework.orm.jpa.JpaSystemException: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.tgt.mkt.customdam.domain.metadata.Store out of START_ARRAY token
 at [Source: [{"id": "T1230", "description": "store description"}]; line: 1, column: 1]; nested exception is org.hibernate.HibernateException: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.tgt.mkt.customdam.domain.metadata.Store out of START_ARRAY token
 at [Source: [{"id": "1230", "description": "store description"}]; line: 1, column: 1]

Here is a snippet of the request body that I sent to save the info with Postman. Is there a reason Jackson would be able to deserialize a list from a REST call but not from the DB?

"stores": [
        {
            "id": "T1230",
            "description": "store description"
        }
    ],

Upvotes: 2

Views: 2297

Answers (1)

user10993231
user10993231

Reputation: 111

Found the solution in a different project my team is working on. I'm not sure how or why but updating the @Parameter by prepending "[L" and adding a semicolon at the end of the classname fixed it.

@Parameter(name = JSONBUserType.CLASS,
            value = "[Lcom.tgt.mkt.customdam.domain.metadata.Store;")

and updating the field to a Store[].

    @Column(name = "stores")
    @Type(type = "stores")
    private Store[] stores;

Upvotes: 2

Related Questions