为了避免无限递归,我使用了@JsonManagedReference和@JsonBackReference。但是在检索结果时,我只能以一种方式获得预期结果。

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="THIRD_TABLE",
    joinColumns={@JoinColumn(name="STUDENT_ID")},
    inverseJoinColumns={@JoinColumn(name="TEACHER_ID")})
    @JsonManagedReference
    private Set<Teacher> teachers = new HashSet<>();

-----------
    @ManyToMany(mappedBy="teachers")
    @JsonBackReference
    private Set<Student> winners = new HashSet<>();


让每个学生的老师都能很好地工作,但是让每个老师的学生都行不通。 JsonBackReference可以防止这种情况。

是否可以将两个注释都放在一个字段上并使它以两种方式工作。

最佳答案

如果只想避免递归,则可以使用@JsonIdentityInfo。它将为每个对象生成ID,如果重复,则将重复的对象替换为其ID。

这是一个简单的父/子示例:

@JsonIdentityInfo(generator=IntSequenceGenerator.class)
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class Parent {
  private List<Child> children=new ArrayList<>();
  private String name="parent";

  public Parent() {
    super();
    children.add(new Child(this,"foo"));
    children.add(new Child(this,"bar"));
  }

  public List<Child> getChildren() {
    return children;
  }

}
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class Child {
  private Parent parent;
  private String pseudo="toto";
  public Child(Parent parent, String pseudo) {
    super();
    this.parent = parent;
    this.pseudo = pseudo;
  }

}



public class SOJson {
  public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    Parent object=new Parent();
    String json1 = objectMapper.writeValueAsString( object);
    System.out.println("write parent: "+json1);
    String json2 = objectMapper.writeValueAsString(object.getChildren().get(0));
    System.out.println("write child: "+json2);

  }
}


结果:

write parent: {"@id":1,"children":[{"parent":1,"pseudo":"foo"},{"parent":1,"pseudo":"bar"}],"name":"parent"}
write child: {"parent":{"@id":1,"children":[{"parent":1,"pseudo":"foo"},{"parent":1,"pseudo":"bar"}],"name":"parent"},"pseudo":"foo"}


您会看到子代和父代之间存在递归,如果删除@JsonIdentityInfo,则会产生stackoverflow。

当然,您将需要在某处停止递归,否则您将转储所有数据库!使用@jsonIgnore可以在某个地方停止递归,或者使用Hibernate4Module可以停止对已卸载的惰性属性的递归。 (我更喜欢同时使用)

关于java - hibernate 多对多双向-两种方式@JsonManagedReference和@JsonBackReference,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42650385/

10-09 05:51