【发布时间】:2020-09-19 19:45:07
【问题描述】:
我在 Postgres 中创建了一个表 Category ,其中包含父类别和子类别以及对自身的引用(这是一个自联接表)
该表由以下列组成:id, parent_id, start_date, end_date, status
我也有一行用于 id = 0 的根父级。因此,任何第一级类别都将根作为其父级。
示例:服装 > 女性。这里 Apparel(id=1) 是 parent_id = 0 的一级类别。 Women 是 parent_id = 1 的另一个类别。
我在我的桌子上使用 Spring JpaRepository findAll,这会导致无限递归。
POJO
@Table(name = "ofr_category")
@Getter
@Setter
@NoArgsConstructor
public class Category {
@Id
@Column(name = "cat_id", updatable = true, unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CATEGORY_SEQ")
@SequenceGenerator(sequenceName = "CATEGORY_ID_SEQ", allocationSize = 1, name = "CATEGORY_SEQ")
private Long id;
@Column(name = "cat_name")
private String name;
@Column(name = "cat_status")
private String status;
@Column(name = "start_date")
private LocalDate startDate;
@Column(name = "end_date")
private LocalDate endDate;
@Column(name = "parent_id")
private Long parentId;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", insertable = false, updatable = false)
private Category parentCategory;
@JsonManagedReference
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parentCategory")
private List<Category> childCategories;
public Category getParentCategory(){
return parentCategory;
}
}
看到异常
"Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: java.util.ArrayList[0]->com.test.category.dataobject.Category[\"parentCategory\"]->com.test.category.dataobject.Category[\"parentCategory\"]->com.test.category.dataobject.Category[\"parentCategory\"])",
【问题讨论】:
-
这是杰克逊的例外,不是 JPA。它无法解析递归关系 - 您需要告诉它如何处理它,并且看起来您的 JsonManagedReference 和 JsonBackReference 注释没有被拾取。也许将它们移到方法访问器中,就像您告诉杰克逊使用它们一样。
-
感谢您的意见,克里斯。当我尝试与他们的孩子一起访问 1 级类别时,我没有看到任何异常。在上面的示例中,如果我访问服装,我看不到任何问题。当我访问作为所有级别 1 类别的父级的根 (id = 0) 时会出现问题。我发现了问题:(愚蠢的错误。我不小心将 root 的父级设为 0,应该为 null。这导致循环获取
-
鉴于我上面定义的表结构,获取整个类别树的最佳方法是什么?如果我执行 find(0) 获取整个树的根元素,我觉得性能真的很差。有替代解决方案吗?任何帮助表示赞赏。
-
您的 JPA 提供者将具有提供者特定的选项,例如批量提取,这可能会有所帮助。参见eclipse.org/eclipselink/documentation/2.7/solutions/… 的示例,这些通常在具有多个级别的自引用表上更加困难。您可能需要尝试不同的选项和解决方案并进行比较,看看哪些最适合您的用例和数据集。
标签: spring jpa infinite-loop