mysql - 在 ManyToMany 双向映射中 findAll() 获取行,每行包含其子项,而子项又包含其自身

标签 mysql hibernate spring-boot kotlin

我的数据模型具有ManyToMany双向映射,如下所示。

一个产品可以有多个类别,同样的类别可以有多个产品。我正在使用链接表来维护关系。

“类别”实体定义如下:

@Entity(name = "categories")
class Categories(
        @Id
        @GeneratedValue
        @Column(name="cat_id", unique = true, nullable = false)
        var id: Integer,
        @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name = "categories_product", joinColumns = [JoinColumn(name = "cat_id")], inverseJoinColumns = [JoinColumn(name = "prd_id")])
        @JsonIgnoreProperties("productsSet")
        var productsSet: MutableSet<Products>
)

“产品”实体有一个列表作为逆映射:

@Entity(name = "products")
class Products(
        @Id
        @GeneratedValue
        @Column(name="prd_id", unique = true, nullable = false)
        var id: Integer,
        @ManyToMany(fetch = FetchType.LAZY, mappedBy = "productsSet")
        @JsonIgnoreProperties("productsSet")
        var categories: MutableSet<Categories>
)

我的映射表“categories_product”有两列“cat_id”和“prd_id”,分别引用“categories”和“products”表。

我有一个实现 CrudRepository 的 ProductsRepository 和 CategoryRepository。

从MappedBy侧(即ProductsRepository)调用findAll()可以正常工作,如下所示:

[
   {
      "id":1,
      "name":"Cricket Bat",
      "price":10.0,
      "categories":[
         {
            "id":1,
            "name":"Sports",
            "description":"Sports items"
         }
      ]
   },
   {
      "id":2,
      "name":"Spring Boot",
      "price":100.0,
      "categories":[
         {
            "id":2,
            "name":"Books",
            "description":"Book items"
         }
      ]
   }
]

但是,从拥有方(即类别)调用 findAll() 会返回其所有产品,其中也包含其引用的类别,如下所示:

[
   {
      "id":1,
      "name":"Sports",
      "description":"Sports items",
      "productsSet":[
         {
            "id":1,
            "name":"Cricket Bat",
            "price":10.0,
            "categories":[
               {
                  "id":1,
                  "name":"Sports",
                  "description":"Sports items"
               }
            ]
         }
      ]
   },
   {
      "id":2,
      "name":"Books",
      "description":"Book items",
      "productsSet":[
         {
            "id":2,
            "name":"Spring Boot",
            "price":100.0,
            "categories":[
               {
                  "id":2,
                  "name":"Books",
                  "description":"Book items"
               }
            ]
         }
      ]
   }
]

如何使拥有方 (CategoriesRepository) 的 findAll() 仅返回其子项而不是映射方 (ProductsRepository) 中的子项的子项?

最佳答案

为了其他人的利益,我列出了评论中@JBNizet给出的解决方案。谢谢,JB 尼泽特!

使用 @ManyToMany 时,必须包含 @JsonIgnoreProperties 以避免由于递归获取记录而出现 StackOverFlow 异常。

因此在拥有方定义 @JsonIgnoreProperties 以忽略子元素,如下所示:

@ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name = "categories_product", joinColumns = [JoinColumn(name = "cat_id")], inverseJoinColumns = [JoinColumn(name = "prd_id")])
        @JsonIgnoreProperties("categories")
        var productsSet: MutableSet<Products>

并在映射端定义@JsonIgnoreProperties以忽略父元素,如下所示:

@ManyToMany(fetch = FetchType.LAZY, mappedBy = "productsSet")
        @JsonIgnoreProperties("productsSet")
        var categories: MutableSet<Categories>

关于mysql - 在 ManyToMany 双向映射中 findAll() 获取行,每行包含其子项,而子项又包含其自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56413301/

相关文章:

python - Django-Admin 面板不会显示通过 phpmyadmin 插入的记录?

mysql - 多级类别的数据库结构(最佳方法)

mysql - 数据建模 : vehicle's year, 品牌和型号?

hibernate - Play Framework 和集合在模型类中的使用

java - 您需要数据库事务来读取数据吗?

java - 如何使用 MySQL 后端在 JPA Spring Boot 微服务中建模三向关系

php - MySQL(i) "Too many connections"怎么办?

java - 如何测试使用 @PreAuthorized(hasAnyAuthority(...)) 注释的 Spring Boot Controller 方法

java - javax.persistence.PersistenceContext.synchronization() 中的错误

java - Hql如何更新有限制的表?