REST API 无限循环
REST API Infinite loop
我的 API 显示了地址字段的无限循环
当我插入@JsonIgnore、@JsonManagedReference 或@JsonBackReference 时
我可以清楚地看到一个结果,但我没有嵌套的地址字段。
我应该怎么做才能让那个地址字段也只有一个结果?
这些是我的主要实体:
1.Property
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Data
@Table(name = "property")
public class Property {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_property")
private int id_property;
@Column(name = "title")
private String title;
@Column(name = "type")
private String type;
@Column(name = "room")
private String room;
@Column(name = "price")
private double price;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "address_id_address")
// @JsonBackReference
private Address address;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id_user")
// @JsonBackReference
private User user;
}
- 用户
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "user")
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user")
private int id_user;
@Column(name = "username")
private String username;
@Column(name = "name")
private String name;
@Column(name = "lastname")
private String lastname;
@Column(name = "phone")
private String phone;
@Column(name = "notes")
private String notes;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_address_id_user_address")
// @JsonManagedReference
private UserAddress userAddress;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
// @JsonManagedReference
private List<Property> property = new ArrayList<>();
}
- 地址
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name="address")
class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_address")
private int id_address;
@Column(name = "city")
private String city;
@Column(name = "municipality")
private String municipality;
@Column(name = "place")
private String place;
@Column(name = "street")
private String street;
@Column(name = "house_number")
private double house_number;
@OneToOne(mappedBy = "address")
// @JsonManagedReference
private Property property;
}
您在 属性 和地址 class 之间存在循环依赖。为了阻止无限 JSON 序列化循环,您可以在相关属性的一侧添加 @JsonIgnore 注释
您实际上在代码中找到了问题的解决方案,但关键注释被注释掉并位于错误的位置(根据您的要求)。解决此问题的方法之一是使用 @JsonManagedReference
和 @JsonBackReference
,如下所示:
@Entity
@Data
@Table(name = "property")
public class Property {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_property")
private int id_property;
@Column(name = "title")
private String title;
@Column(name = "type")
private String type;
@Column(name = "room")
private String room;
@Column(name = "price")
private double price;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "address_id_address")
@JsonManagedReference
private Address address;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id_user")
@JsonBackReference
private User user;
}
@Entity
@Getter
@Setter
@Table(name = "user")
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user")
private int id_user;
@Column(name = "username")
private String username;
@Column(name = "name")
private String name;
@Column(name = "lastname")
private String lastname;
@Column(name = "phone")
private String phone;
@Column(name = "notes")
private String notes;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_address_id_user_address")
private UserAddress userAddress;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
@JsonManagedReference
private List<Property> property = new ArrayList<>();
}
@Entity
@Getter
@Setter
@Table(name="address")
class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_address")
private int id_address;
@Column(name = "city")
private String city;
@Column(name = "municipality")
private String municipality;
@Column(name = "place")
private String place;
@Column(name = "street")
private String street;
@Column(name = "house_number")
private double house_number;
@OneToOne(mappedBy = "address")
@JsonBackReference
private Property property;
}
请记住以下几点:
@JsonManagedReference
是关系的前向部分:正常序列化的部分。
@JsonBackReference
是关系后面的部分:连载时会省略。
如果想对关系后面的部分有引用,可以使用@JsonIdentityInfo
,如下:
@Entity
@Data
@Table(name = "property")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_property")
public class Property {
(...)
}
@Entity
@Getter
@Setter
@Table(name = "user")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_user")
class User {
(...)
}
@Entity
@Getter
@Setter
@Table(name="address")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_address")
class Address{
(...)
}
您可以在以下在线资源中阅读有关这些和其他技术的更多信息:https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion。
我的 API 显示了地址字段的无限循环
当我插入@JsonIgnore、@JsonManagedReference 或@JsonBackReference 时 我可以清楚地看到一个结果,但我没有嵌套的地址字段。
我应该怎么做才能让那个地址字段也只有一个结果?
这些是我的主要实体:
1.Property
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Data
@Table(name = "property")
public class Property {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_property")
private int id_property;
@Column(name = "title")
private String title;
@Column(name = "type")
private String type;
@Column(name = "room")
private String room;
@Column(name = "price")
private double price;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "address_id_address")
// @JsonBackReference
private Address address;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id_user")
// @JsonBackReference
private User user;
}
- 用户
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "user")
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user")
private int id_user;
@Column(name = "username")
private String username;
@Column(name = "name")
private String name;
@Column(name = "lastname")
private String lastname;
@Column(name = "phone")
private String phone;
@Column(name = "notes")
private String notes;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_address_id_user_address")
// @JsonManagedReference
private UserAddress userAddress;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
// @JsonManagedReference
private List<Property> property = new ArrayList<>();
}
- 地址
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name="address")
class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_address")
private int id_address;
@Column(name = "city")
private String city;
@Column(name = "municipality")
private String municipality;
@Column(name = "place")
private String place;
@Column(name = "street")
private String street;
@Column(name = "house_number")
private double house_number;
@OneToOne(mappedBy = "address")
// @JsonManagedReference
private Property property;
}
您在 属性 和地址 class 之间存在循环依赖。为了阻止无限 JSON 序列化循环,您可以在相关属性的一侧添加 @JsonIgnore 注释
您实际上在代码中找到了问题的解决方案,但关键注释被注释掉并位于错误的位置(根据您的要求)。解决此问题的方法之一是使用 @JsonManagedReference
和 @JsonBackReference
,如下所示:
@Entity
@Data
@Table(name = "property")
public class Property {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_property")
private int id_property;
@Column(name = "title")
private String title;
@Column(name = "type")
private String type;
@Column(name = "room")
private String room;
@Column(name = "price")
private double price;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "address_id_address")
@JsonManagedReference
private Address address;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id_user")
@JsonBackReference
private User user;
}
@Entity
@Getter
@Setter
@Table(name = "user")
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user")
private int id_user;
@Column(name = "username")
private String username;
@Column(name = "name")
private String name;
@Column(name = "lastname")
private String lastname;
@Column(name = "phone")
private String phone;
@Column(name = "notes")
private String notes;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_address_id_user_address")
private UserAddress userAddress;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
@JsonManagedReference
private List<Property> property = new ArrayList<>();
}
@Entity
@Getter
@Setter
@Table(name="address")
class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_address")
private int id_address;
@Column(name = "city")
private String city;
@Column(name = "municipality")
private String municipality;
@Column(name = "place")
private String place;
@Column(name = "street")
private String street;
@Column(name = "house_number")
private double house_number;
@OneToOne(mappedBy = "address")
@JsonBackReference
private Property property;
}
请记住以下几点:
@JsonManagedReference
是关系的前向部分:正常序列化的部分。@JsonBackReference
是关系后面的部分:连载时会省略。
如果想对关系后面的部分有引用,可以使用@JsonIdentityInfo
,如下:
@Entity
@Data
@Table(name = "property")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_property")
public class Property {
(...)
}
@Entity
@Getter
@Setter
@Table(name = "user")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_user")
class User {
(...)
}
@Entity
@Getter
@Setter
@Table(name="address")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_address")
class Address{
(...)
}
您可以在以下在线资源中阅读有关这些和其他技术的更多信息:https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion。