无法使用杰克逊反序列化包含 2 个具有相同 ID 的对象的 Json

Posted

技术标签:

【中文标题】无法使用杰克逊反序列化包含 2 个具有相同 ID 的对象的 Json【英文标题】:Unable to deserialize Json that contain 2 objects with the same ID using jackson 【发布时间】:2018-04-15 03:21:39 【问题描述】:

我已经使用jackson JsonIdentityInfo 来处理spring mvc 中的递归对象引用。 我遇到了一个问题,即无法反序列化包含 2 个具有相同 ID 的对象的 Json。



    "organizations": [
        
            "organizationId": 1,            
            "organizationName": "org1",
            "enterprise": 
                "enterpriseId": 1,              
                "enterpriseName": "ent1",
                "organizations": null
            
        ,
        
            "organizationId": 2,            
            "organizationName": "org2",
            "enterprise": 1
        
    ]

如果您在上面看到,两个组织都映射到企业“1”。对于第一个组织,它是整个企业对象,但对于组织 2,它只提供 ID。 我还需要为组织 2 获取整个对象。

我的 POJO 声明:

@Entity
@Table(name = "organization")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "organizationId")
public class Organization implements Serializable 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "organization_id")
    private Long organizationId;

    ...

    @ManyToOne
    @JoinTable(name = "enterprise_organization", joinColumns = 
            @JoinColumn(name = "organization_id") , inverseJoinColumns =  @JoinColumn(name = "enterprise_id") )
    private Enterprise enterprise;

    ...


@Entity
@Table(name = "enterprise")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "enterpriseId")
public class Enterprise extends BaseEntity implements Serializable 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "enterprise_id")
    private Long enterpriseId;
    ...

    @OneToMany(mappedBy = "enterprise")
    private List<Organization> organizations;
    ...

我搜索了谷歌和 SO,但没有运气。

反序列化包含 2 个具有相同 ID 的对象的 Json 需要哪些更改?

【问题讨论】:

如果将private List&lt;Organization&gt; organizations; 更改为private Set&lt;Organization&gt; organizations; 会发生什么 @Patrick 我已将列表更改为设置。还是同样的问题。仅供参考,我正在使用映射表。所以数据类型没有问题。 @Krishna 不要认为您可以通过简单的通用方式做到这一点。可能可以尝试***.com/a/24684251/1032167 或实现自定义 id 生成器,但我认为它会比自定义序列化器/反序列化器更难阅读和理解。 @Krishna 顺便说一句,如果你只需要反序列化,你可以看看 github.com/varren/… 在过去有类似的问题。它更像是一种解决方案...... @varren 感谢您的回复。在您提供的链接中,它是用“id”硬编码的,我该如何为不同的 id 名称做它,如“enterpriseId”、“organizationId”等。? 【参考方案1】:

经过多次尝试,@JsonIgnoreProperties 解决了我的问题。

示例:“@JsonIgnoreProperties(allowSetters = true, value = "enterprise" )"

【讨论】:

以上是关于无法使用杰克逊反序列化包含 2 个具有相同 ID 的对象的 Json的主要内容,如果未能解决你的问题,请参考以下文章

杰克逊,反序列化具有私有字段的类和没有注释的 arg-constructor

具有完整 POJO 数据绑定的杰克逊自定义过滤器

如何使用杰克逊制作自定义反序列化器将数字(即部门 ID)转换为部门对象?

杰克逊:使用时区 id 解析 ZonedDateTime

杰克逊:反序列化为每个值都具有正确类型的 Map<String, Object>

当我尝试反序列化对象列表时,杰克逊抛出错误映射异常