无法写入 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 ModelTransport Objects

你的多个实体本身拥有彼此。 例如,Product 的对象为 User,而 User 的对象为 Product

要解决这个问题,你必须写

@JsonBackReference(value = "user-product")
private User user;

Productclass, 和

@JsonManagedReference(value = "user-product")
private Product product;

userclass。 在每个领域和每个互相调用的 class 中执行此操作。

另外,看看这个