杰克逊在JSON回复中返回不需要的号码

时间:2015-09-23 18:00:25

标签: json hibernate jackson

我在我的JSON响应中看到一个奇怪的问题,我从资源中检索一个集合,给定资源的ID:数字(可能列表索引?)在之前或之前显示在JSON对象之后。

[
    {
        "id": 1,
        "dateCreated": [
            2015,
            9,
            23,
            18,
            9,
            33,
            23000000
        ],
        "dateModified": [
            2015,
            9,
            23,
            18,
            9,
            33,
            23000000
        ],
        "name": "First Check-In",
        "description": null,
        "qualifyingPeriodStartDate": [
            2015,
            9,
            1,
            0,
            0
        ],
        "customers": [],
        "campaign": {
            "id": 1,
            "dateCreated": [
                2015,
                9,
                24,
                14,
                59,
                31,
                474000000
            ],
            "dateModified": [
                2015,
                9,
                24,
                14,
                59,
                31,
                474000000
            ],
            "name": "Background campaign",
            "startDate": [
                2015,
                9,
                1,
                0,
                0
            ],
            "endDate": [
                2016,
                9,
                1,
                0,
                0
            ],
            "chain": null,
            "surveys": [],
            "achievements": [
                1,
                {
                    "id": 2,
                    "dateCreated": [
                        2015,
                        9,
                        23,
                        18,
                        10,
                        21,
                        341000000
                    ],
                    "dateModified": [
                        2015,
                        9,
                        23,
                        18,
                        10,
                        21,
                        341000000
                    ],
                    "name": "First Survey Completion",
                    "description": null,
                    "qualifyingPeriodStartDate": [
                        2015,
                        9,
                        1,
                        0,
                        0
                    ],
                    "customers": [],
                    "campaign": 1,
                    "reward": {
                        "id": 1,
                        "dateCreated": [
                            2015,
                            9,
                            24,
                            14,
                            59,
                            31,
                            815000000
                        ],
                        "dateModified": [
                            2015,
                            9,
                            24,
                            14,
                            59,
                            31,
                            815000000
                        ],
                        "name": "McFlurry",
                        "customer": null,
                        "rewardPointValue": 0,
                        "chain": null,
                        "achievements": [
                            1,
                            2,
                            {
                                "id": 3,
                                "dateCreated": [
                                    2015,
                                    9,
                                    23,
                                    18,
                                    10,
                                    29,
                                    691000000
                                ],
                                "dateModified": [
                                    2015,
                                    9,
                                    23,
                                    18,
                                    10,
                                    29,
                                    691000000
                                ],
                                "name": "First Three Check-Ins",
                                "description": null,
                                "qualifyingPeriodStartDate": [
                                    2015,
                                    9,
                                    8,
                                    0,
                                    0
                                ],
                                "customers": [],
                                "campaign": {
                                    "id": 2,
                                    "dateCreated": [
                                        2015,
                                        9,
                                        24,
                                        14,
                                        59,
                                        31,
                                        782000000
                                    ],
                                    "dateModified": [
                                        2015,
                                        9,
                                        24,
                                        14,
                                        59,
                                        31,
                                        782000000
                                    ],
                                    "name": "September campaign",
                                    "startDate": [
                                        2015,
                                        9,
                                        11,
                                        0,
                                        0
                                    ],
                                    "endDate": [
                                        2015,
                                        9,
                                        18,
                                        0,
                                        0
                                    ],
                                    "chain": null,
                                    "surveys": [],
                                    "achievements": [
                                        3
                                    ],
                                    "locations": []
                                },
                                "reward": 1,
                                "numActionsRequired": 3,
                                "actionType": "check-in",
                                "customerActions": []
                            }
                        ]
                    },
                    "numActionsRequired": 1,
                    "actionType": "survey-completion",
                    "customerActions": []
                }
            ],
            "locations": []
        },
        "reward": 1,
        "numActionsRequired": 1,
        "actionType": "check-in",
        "customerActions": []
    },
    2
]

任何人都可以提供一些有关为什么会发生这种情况的见解,以及如何摆脱这些数字?对于它的价值,我使用Spring with Hibernate和jackson-datatype-hibernate模块。 (https://github.com/FasterXML/jackson-datatype-hibernate

我也使用@JsonIdentityInfo注释而不是@JsonManagedReference和@JsonBackReference。

编辑1

父实体:

@Entity
@DynamicUpdate
@SelectBeforeUpdate
@NamedQuery(name = "Campaign.byId", query = "from Campaign where id=:id")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Campaign.class)
public class Campaign extends NamedEntity {
    private static final long serialVersionUID = 1781401593603214034L;
    private LocalDateTime startDate = LocalDateTime.now();
    private LocalDateTime endDate = LocalDateTime.now();
    @ManyToOne
    @JoinColumn(name = "chain_id")
    private Chain chain;
    @ManyToMany(mappedBy = "campaigns", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Survey> surveys = new ArrayList<Survey>();
    @OneToMany(mappedBy = "campaign", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Achievement> achievements = new ArrayList<Achievement>();
    @ManyToMany(mappedBy = "campaigns", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Location> locations = new ArrayList<Location>();
    private boolean runsIndefinitely;

子实体:

@Entity
@DynamicUpdate
@SelectBeforeUpdate
@NamedQueries({ @NamedQuery(name = "Achievement.byId", query = "from Achievement where id=:id"),
        @NamedQuery(name = "EligibleAchievements.byCustomerActionId", query = "from Achievement a where :customerActionId not in (select ca.id from a.customerActions as ca) and :customerId not in (select c.id from a.customers as c)"),
        @NamedQuery(name = "CountedAchievements.byCustomerActionId", query = "from Achievement a where :id in (select ca.id from a.customerActions as ca)") })
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Achievement.class)
public class Achievement extends NamedEntity {
    private static final long serialVersionUID = -8317978091374706947L;
    private String description;
    private LocalDateTime qualifyingPeriodStartDate = LocalDateTime.now();
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "customers_achievements", joinColumns = @JoinColumn(name = "achievement_id") , inverseJoinColumns = @JoinColumn(name = "customer_id") )
    private List<Customer> customers = new ArrayList<Customer>();
    @ManyToOne
    @JoinColumn(name = "campaign_id")
    private Campaign campaign;
    @ManyToOne
    @JoinColumn(name = "reward_id")
    private Reward reward;
    private int numActionsRequired;
    private String actionType;
    @ManyToMany(mappedBy = "achievements", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<CustomerAction> customerActions = new ArrayList<CustomerAction>();

编辑2

我正在从此服务端点方法中检索属于特定广告系列的所有成就:

@RequestMapping(value = "{id}/achievements", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public List<Achievement> getAchievementsFromCampaign(@PathVariable int id) {
    List<Achievement> achievements = campaignService.getCampaignAchievements(id);
    return achievements;
}

编辑3

似乎如果我在对父实体(Campaign)的引用上使用JsonIgnore注释,那么数字将替换为我期望的其他JSON对象。我想这是为了防止重复数据显示在JSON响应中。

因此,数字实际上是引用第一个嵌套的Achievement JSON对象中已列出的其他Achievement对象的对象ID。

1 个答案:

答案 0 :(得分:0)

似乎答案是将JSON身份引用始终设置为true;见https://fasterxml.github.io/jackson-annotations/javadoc/2.1.0/com/fasterxml/jackson/annotation/JsonIdentityReference.html

父实体:

@Entity
@DynamicUpdate
@SelectBeforeUpdate
@NamedQuery(name = "Campaign.byId", query = "from Campaign where id=:id")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Campaign.class)
public class Campaign extends NamedEntity {
    @OneToMany(mappedBy = "campaign", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JsonIdentityReference(alwaysAsId=true)
    private List<Achievement> achievements = new ArrayList<Achievement>();

子实体:

@Entity
@DynamicUpdate
@SelectBeforeUpdate
@NamedQueries({ @NamedQuery(name = "Achievement.byId", query = "from Achievement where id=:id"),
        @NamedQuery(name = "EligibleAchievements.byCustomerActionId", query = "from Achievement a where :customerActionId not in (select ca.id from a.customerActions as ca) and :customerId not in (select c.id from a.customers as c)"),
        @NamedQuery(name = "CountedAchievements.byCustomerActionId", query = "from Achievement a where :id in (select ca.id from a.customerActions as ca)") })
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Achievement.class)
public class Achievement extends NamedEntity {
    @ManyToOne
    @JoinColumn(name = "campaign_id")
    @JsonIdentityReference(alwaysAsId=true)
    private Campaign campaign;

产生的JSON响应:

[
    {
        "id": 1,
        "dateCreated": [
            2015,
            9,
            23,
            18,
            9,
            33,
            23000000
        ],
        "dateModified": [
            2015,
            9,
            23,
            18,
            9,
            33,
            23000000
        ],
        "name": "First Check-In",
        "description": null,
        "qualifyingPeriodStartDate": [
            2015,
            9,
            1,
            0,
            0
        ],
        "customers": [],
        "campaign": 1,
        "reward": {
            "id": 1,
            "dateCreated": [
                2015,
                9,
                24,
                15,
                12,
                37,
                188000000
            ],
            "dateModified": [
                2015,
                9,
                24,
                15,
                12,
                37,
                188000000
            ],
            "name": "McFlurry",
            "customer": null,
            "rewardPointValue": 0,
            "chain": null,
            "achievements": [
                1,
                2,
                3
            ]
        },
        "numActionsRequired": 1,
        "actionType": "check-in",
        "customerActions": []
    },
    {
        "id": 2,
        "dateCreated": [
            2015,
            9,
            23,
            18,
            10,
            21,
            341000000
        ],
        "dateModified": [
            2015,
            9,
            23,
            18,
            10,
            21,
            341000000
        ],
        "name": "First Survey Completion",
        "description": null,
        "qualifyingPeriodStartDate": [
            2015,
            9,
            1,
            0,
            0
        ],
        "customers": [],
        "campaign": 1,
        "reward": 1,
        "numActionsRequired": 1,
        "actionType": "survey-completion",
        "customerActions": []
    },
    {
        "id": 3,
        "dateCreated": [
            2015,
            9,
            23,
            18,
            10,
            29,
            691000000
        ],
        "dateModified": [
            2015,
            9,
            23,
            18,
            10,
            29,
            691000000
        ],
        "name": "First Three Check-Ins",
        "description": null,
        "qualifyingPeriodStartDate": [
            2015,
            9,
            8,
            0,
            0
        ],
        "customers": [],
        "campaign": 2,
        "reward": 1,
        "numActionsRequired": 3,
        "actionType": "check-in",
        "customerActions": []
    }
]