如何在 Spring Boot 中使用 JsonIgnore 来停止无限循环? [复制]

Posted

技术标签:

【中文标题】如何在 Spring Boot 中使用 JsonIgnore 来停止无限循环? [复制]【英文标题】:How to use JsonIgnore in Spring Boot to stop infinite loop? [duplicate] 【发布时间】:2021-11-22 13:34:12 【问题描述】:

在我的项目中,用户和产品之间存在多对多关系。一个用户可以拥有多个产品,一个产品可以由多个用户拥有。

用户.java

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable( name = "user_product",
                joinColumns = @JoinColumn(name = "user_id"),
                inverseJoinColumns = @JoinColumn(name = "product_id"))
    private List<Product> listOfProductsForUser;

Product.java

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "listOfProductsForUser")
    private List<User> listOfUsersForProduct;

在我的控制器中,我有一条路径可以让我获得所有用户以及与此用户关联的嵌套产品。

[
    
        "userId": 1,
        "userName": "Fido",
        "age": 3,
        "listOfProductsForUser": [
            
                "productId": 1,
                "productName": "tooth brush",
            ,
            
                "productId": 2,
                "productName": "potatoes",
            ,
            
                "productId": 3,
                "productName": "carrot",
            
        ]
    ,
    
        "userId": 2,
        "userName": "David",
        "age": 12,
        "listOfProductsForUser": [
            
                "productId": 6,
                "productName": "oranges",
            ,
            
                "productId": 7,
                "productName": "tomatoes",
            ,
            
                "productId": 6,
                "productName": "buns",
            
        ]
    
]

这很好,但我现在想获取所有应该有嵌套用户的产品(获取所有产品并查看哪些用户正在使用它们)。 在尝试执行此操作时,我遇到了递归问题,我在 product.java 的 listOfProductsForUser 变量上使用了 JsonIgnore 来停止递归。我怎样才能做到这一点?

【问题讨论】:

如果@JsonIgnore 不能满足您的需求,您可能需要查看@JsonManagedReference@JsonBackReference 【参考方案1】:

有几种方法可以处理这种双向关系问题。我认为@JsonIdentityInfo 是您的最佳方式。

您需要做的是更改您的UserProduct 类,如下所示。

//other annotations
@JsonIdentityInfo(
  generator = ObjectIdGenerators.PropertyGenerator.class, 
  property = "userId")
public class User 
    // your code

//other annotations
@JsonIdentityInfo(
  generator = ObjectIdGenerators.PropertyGenerator.class, 
  property = "productId")
public class Product 
    // your code

注意:更多信息here

【讨论】:

【参考方案2】:

尝试以下方法:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable( name = "user_product",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "product_id"))
@JsonManagedReference
private List<Product> listOfProductsForUser;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "listOfProductsForUser")

@JsonBackReference
private List<User> listOfUsersForProduct;

这两个注解(@JsonManagedReference 和 @JsonBackReference)避免了无限递归。


我误解了这个问题。 listOfUsersForProductlistOfProductsForUser 都应该出现在 JSON 中。前面的解决方案省略了listOfUsersForProduct。要同时拥有两者,您需要使用@ray 已经建议的@JsonIdentityInfo

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "userId")
public class User  
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "productId")
public class Product  

【讨论】:

它停止了递归,但是当我获得所有产品时,我仍然无法获得 User listOfUsersForProduct 的数组。 这其实很奇怪。尝试交换注释。我已经编辑了我的答案。 我换了。现在它翻转了。我现在可以通过 listOfUsersForProduct 数组访问用户列表,但是当我从 UserRepository 中获取所有时,我无法通过 listOfProductsForUser 获取产品列表。 等等,你想同时拥有listOfUsersForProductlistOfProductsForUser 吗?在那种情况下,我误解了你的问题。 我已经更新了我的答案。这基本上是@ray 已经建议的内容,所以对他表示敬意。如果它确实有效,请接受并支持他的回答并支持我的回答;)

以上是关于如何在 Spring Boot 中使用 JsonIgnore 来停止无限循环? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中使用 Spring Security 启用 CORS

如何在 Spring Boot 中使用 Spring Security 配置 CORS? [复制]

如何在Spring Boot 中使用 HandlerMethodArgumentResolver

spring boot 如何使用多线程

如何在 spring-boot 中替换最新的 Jetty 9?

如何在 Spring Boot 中手动新建实例中使用 @Autowired