无法写入 JSON: 无限递归
Could not write JSON: Infinite recursion
我在 Postman 或浏览器中 运行 查询时出现 Whosebug 递归错误。
当我 运行 说:
.w.s.m.s.DefaultHandlerExceptionResolver:无法写入 JSON:无限递归(WhosebugError);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException: 无限递归 (WhosebugError)
这是模型 类 :
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String title;
@NotNull
private String description;
@NotNull
private double price;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "category_id", nullable = false)
private Category category;
private boolean isSealed;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "currency_id", nullable = false)
private Currency currency;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Nullable
@OneToMany(mappedBy = "product",
cascade = CascadeType.ALL, orphanRemoval = true)
private List<Images> images;
private Date createdDate = new Date();
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "product")
private View view;
@OneToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="type_id")
private Type type;
private Long viewCount; }
@Entity public class Images{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String imagePath;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
private Product product; }
@Entity public class User implements UserDetails, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotEmpty
private String fullName;
@NotEmpty
@Email
@Column(unique = true)
private String email;
@NotNull
@Column(unique = true)
private int phoneNumber;
@NotEmpty
@Size(min = 5)
private String password;
private Date createAt = new Date();
@Nullable
private String picPath;
@Nullable
private String token;
@ManyToMany
@JoinTable(name = "user_roles", joinColumns = {@JoinColumn(
name = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id")})
private List<Role> roles;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "user")
private Product product;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "user")
private View view; }
@Entity
public class Currency{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String code;
private String currency;
private String region_country;
@OneToOne(mappedBy = "currency", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Product product; }
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String imagePath;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
mappedBy = "category")
private Product product;
@OneToMany(mappedBy = "category", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private Set<Brand> brands; }
@Entity public class Brand {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "category_id", nullable = false)
private Category category; }
@Entity public class View {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "product_id", nullable = false)
private Product product; }
@Entity public class Type {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String name;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "type")
private Product product; }
@Id
private String role;
@ManyToMany(mappedBy = "roles")
private List<User> users;
}
您的数据模型中存在循环。例如,Product
持有 Images
并且 Images
指向 Products
。
这适用于面向对象的世界,因为只有指针引用存储在这些字段中。
然而,当序列化时,实际对象被写为 json 文本。您的 Product
打印 Images
对象,后者又打印 Product
对象,后者再次打印 Image
对象,依此类推。
您需要决定如何表示您的 json,将您的数据库模型映射到简单的普通旧 java 对象并将其用于序列化。这些 POJO 通常称为 View Model 或 Transport Objects。
你的多个实体本身拥有彼此。
例如,Product
的对象为 User
,而 User
的对象为 Product
。
要解决这个问题,你必须写
@JsonBackReference(value = "user-product")
private User user;
在Product
class,
和
@JsonManagedReference(value = "user-product")
private Product product;
在user
class。
在每个领域和每个互相调用的 class 中执行此操作。
另外,看看这个
我在 Postman 或浏览器中 运行 查询时出现 Whosebug 递归错误。
当我 运行 说:
.w.s.m.s.DefaultHandlerExceptionResolver:无法写入 JSON:无限递归(WhosebugError);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException: 无限递归 (WhosebugError)
这是模型 类 :
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String title;
@NotNull
private String description;
@NotNull
private double price;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "category_id", nullable = false)
private Category category;
private boolean isSealed;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "currency_id", nullable = false)
private Currency currency;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Nullable
@OneToMany(mappedBy = "product",
cascade = CascadeType.ALL, orphanRemoval = true)
private List<Images> images;
private Date createdDate = new Date();
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "product")
private View view;
@OneToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="type_id")
private Type type;
private Long viewCount; }
@Entity public class Images{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String imagePath;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
private Product product; }
@Entity public class User implements UserDetails, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotEmpty
private String fullName;
@NotEmpty
@Email
@Column(unique = true)
private String email;
@NotNull
@Column(unique = true)
private int phoneNumber;
@NotEmpty
@Size(min = 5)
private String password;
private Date createAt = new Date();
@Nullable
private String picPath;
@Nullable
private String token;
@ManyToMany
@JoinTable(name = "user_roles", joinColumns = {@JoinColumn(
name = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id")})
private List<Role> roles;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "user")
private Product product;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "user")
private View view; }
@Entity
public class Currency{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String code;
private String currency;
private String region_country;
@OneToOne(mappedBy = "currency", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Product product; }
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String imagePath;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
mappedBy = "category")
private Product product;
@OneToMany(mappedBy = "category", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private Set<Brand> brands; }
@Entity public class Brand {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "category_id", nullable = false)
private Category category; }
@Entity public class View {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "product_id", nullable = false)
private Product product; }
@Entity public class Type {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String name;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "type")
private Product product; }
@Id
private String role;
@ManyToMany(mappedBy = "roles")
private List<User> users;
}
您的数据模型中存在循环。例如,Product
持有 Images
并且 Images
指向 Products
。
这适用于面向对象的世界,因为只有指针引用存储在这些字段中。
然而,当序列化时,实际对象被写为 json 文本。您的 Product
打印 Images
对象,后者又打印 Product
对象,后者再次打印 Image
对象,依此类推。
您需要决定如何表示您的 json,将您的数据库模型映射到简单的普通旧 java 对象并将其用于序列化。这些 POJO 通常称为 View Model 或 Transport Objects。
你的多个实体本身拥有彼此。
例如,Product
的对象为 User
,而 User
的对象为 Product
。
要解决这个问题,你必须写
@JsonBackReference(value = "user-product")
private User user;
在Product
class,
和
@JsonManagedReference(value = "user-product")
private Product product;
在user
class。
在每个领域和每个互相调用的 class 中执行此操作。
另外,看看这个