【问题标题】:how can I use spring to deserialize a postgres jsonb column to a list of objects?如何使用 spring 将 postgres jsonb 列反序列化为对象列表?
【发布时间】:2019-03-22 16:45:30
【问题描述】:

我有一个域对象列表被保存到 postgres jsonb 列(hibernate/jackson)。保存按预期工作,但反序列化时出现映射异常。看起来杰克逊正试图反序列化为域对象,而不是类型指定的域对象列表。

这是领域。它被序列化并正确保存为商店列表。

@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;

这是我在获取保存的信息时遇到的错误。看起来杰克逊正试图将其反序列化为 Store 对象而不是 List&lt;Store&gt;

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]

这是我发送的请求正文的 sn-p,用于使用 Postman 保存信息。 Jackson 是否有理由能够从 REST 调用中反序列化列表,但不能从 DB 中反序列化?

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

【问题讨论】:

  • Jackson 期望 JSON Object 但它看到 JSON Array。您需要以某种方式提供List&lt;com.project.domain.metadata.Store&gt;。检查:Storing a List<SomeClass> as JSON in a text field with HibernateHow to map JSON collections using JPA and Hibernate
  • 是的,它需要一个 JSON 对象。我的问题是为什么。当我保存数据时,它接受对象列表并正确保存。当我使用具有相同字段(即对象列表)的相同域对象获取相同数据时,杰克逊需要一个对象而不是对象列表。为什么杰克逊从 REST 调用正确反序列化为对象列表,但在从数据库中获取时尝试反序列化为对象?从 REST 调用和数据库反序列化时,我使用具有相同字段的相同域对象。

标签: hibernate jackson spring-data-jpa


【解决方案1】:

在我的团队正在进行的另一个项目中找到了解决方案。我不确定如何或为什么,但通过在类名末尾添加“[L”并在类名末尾添加分号来更新@Parameter 来修复它。

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

并将该字段更新为 Store[]。

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

【讨论】:

  • JavaDoc 上查看Class.getName(),尤其是class or interface Lclassname; 和:'[' 表示深度的字符
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 2014-03-11
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多