杰克逊似乎没有坚持由Hibernate管理的双向关系

时间:2015-08-25 04:10:46

标签: java json spring hibernate jackson

我很难弄清楚为什么当我将JSON对象发布到我的REST API(使用Spring和Hibernate)时,关系的拥有方并不会在另一方持久存在。

使用 id 字段映射超类:

@MappedSuperClass
public class BaseEntity implements Serializable {
    private static final long serialVersionUID = 11538918560302121L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    ....
    }

拥有类(扩展 NamedEntity ,后者又扩展 BaseEntity ):

@Entity
@DynamicUpdate
@SelectBeforeUpdate
@NamedQuery(name = "Chain.byId", query = "from Chain where id=:id")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope=Chain.class)
public class Chain extends NamedEntity {
    private static final long serialVersionUID = 4727994683438452454L;
    @OneToMany(mappedBy = "chain", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Campaign> campaigns = new ArrayList<Campaign>();
    ....
}

自有班级:

@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 {
    @ManyToOne
    @JoinColumn(name = "chain_id")
    private Chain chain;
    ....
}

我的 RestController 的相关部分:

@RequestMapping(value = "new", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
@ResponseBody
public Chain saveChain(@RequestBody Chain chain) {
    chainDAO.saveChain(chain);
    return chain;
}

JSON请求正文:

{  
  "name": "mcdonald's",
  "campaigns": [
      {
          "name": "summer1"
      }
  ]
}

JSON响应正文的相关部分:

{
  "id": 1,
  "name": "mcdonald's",
  "campaigns": [
    {
      "id": 1,
      "name": "summer1",
      "rewards": [],
      "startDate": null,
      "endDate": null,
      "chain": null,
      "surveys": [],
      "achievements": []
    }
  ],
  "rewards": []
}

我怀疑这实际上是使用@JsonIdentityInfo注释打破无限递归时的预期行为?但是,当我尝试使用 id 字段创建我刚刚创建的 Chain 时,我没有看到嵌套对象( Campaign )了。

我用来检索我刚刚创建的 Chain 对象的GET方法:

@RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public Chain getChain(Model model, @PathVariable int id) {
    Chain chain = chainDAO.getChainById(id).get(0);
    return chain;
}

GET方法的JSON响应主体:

{
  "id": 1,
  "name": "mcdonald's",
  "campaigns": [],
  "rewards": [],
  "managers": [],
  "locations": []
}

如您所见,此 Chain 对象中的广告系列数组现在为空。

1 个答案:

答案 0 :(得分:0)

事实证明,我并没有正确管理双向关系。必须在两端明确设置关系。

@RequestMapping(value = "{id}/campaigns/new", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    @ResponseBody
    public Campaign saveCampaignToChain(@RequestBody Campaign campaign, @PathVariable int id) {
        Chain chain = chainDAO.getChainById(id).get(0);
        chain.getCampaigns().add(campaign);
        campaign.setChain(chain);
        chainDAO.saveChain(chain);
        campaignDAO.saveCampaign(campaign);
        return campaign;
    }