如何在没有递归的情况下使用Dropwizard / Hibernate / Swagger以多对多的关系返回子对象?

时间:2017-03-07 19:09:17

标签: jackson dropwizard

我正在使用Dropwizard和Swagger创建REST API来管理对各种对象的访问。其中两个对象涉及多对多关系,例如:

public class Puppy implements Serializable {
    private Long id;
    private String name;
    @ManyToMany(targetEntity = Trick.class)
    @JoinTable(
        name="puppies_tricks",
        joinColumns=@JoinColumn(name="puppy_id"),
        inverseJoinColumns=@JoinColumn(name="trick_id"))
    private List<Trick> tricks;

    @JsonProperty("tricks")
    public List<Trick> getTricks() { return this.tricks; }
    ...
}    

public class Trick implements Serializable {
    private Long id;
    private String name;
    @ManyToMany(targetEntity = Puppy.class)
    @JoinTable(
        name="puppies_tricks",
        joinColumns=@JoinColumn(name="trick_id"),
        inverseJoinColumns=@JoinColumn(name="puppy_id"))
    private List<Puppy> puppies;

    @JsonProperty("puppies")
    public List<Puppy> getPuppies() { return this.puppies; }
    ...
}    

假设实际数据类似于:

# Tricks:
[{ id: 1, name: 'Roll over' },
{ id: 2, name: 'Play dead' },
{ id: 3, name: 'Steal second' }]

# Puppies:
[{ id: 1, name: 'Flopsy' },
{ id: 2, name: 'Mopsy' },
{ id: 3, name: 'Cottontail' }]

# Puppies_Tricks
[{ puppy_id: 1, trick_id: 1 },
{ puppy_id: 1, trick_id: 2 },
{ puppy_id: 2, trick_id: 2 },
{ puppy_id: 2, trick_id: 3 }]

所以当我GET / puppy / 1时,我希望得到一个像:

这样的结构
{ 
  "id": 1, 
  "name": "Flopsy", 
  "tricks": [ 
    { "id": 1, "name": "Roll over"}, 
    { "id": 2, "name": "Play dead" } ]
}

但我实际得到的是一个嵌套数组:

{ 
  "id": 1, 
  "name": "Flopsy", 
  "tricks": [ 
    { "id": 1, "name": "Roll over", "puppies": [ { "id": 1, "name": "Flopsy" }, ...}, 
    { "id": 2, "name": "Play dead", "puppies": [...] } ]
}

有没有办法告诉Jackson / Dropwizard在获取小狗时停止通过技巧,反之亦然?

Dropwizard 1.0.6,Java 1.8。

3 个答案:

答案 0 :(得分:1)

杰克逊通过@JsonManagedReference @JsonBackReference注释支持对象图序列化。见the documentation here。你可以找到simple example here。 您应该真正更仔细地阅读您正在使用的工具的文档。

已经有an answer that summarizes种可用方法。

答案 1 :(得分:0)

@JsonIgnore
@JsonProperty("puppies")
public List<Puppy> getPuppies() { return this.puppies; }

将停止无限循环

答案 2 :(得分:0)

我的解决方案是创建一个单独的PuppyCore类来实现序列化但不会持久化。这包括基本的Puppy信息(id,name)。类似地,TrickCore只有id和name。

然后Puppy包含Set tricks,使用此getter:

public Set<TrickCore> getTricks();

返回TrickCore对象列表 - 这些对象没有Puppy列表,因此停止递归。 Trick上的类似模式会为Set<PuppyCore>返回getPuppies()