Spring Boot Data JPA中的自我联接-仅显示第一个子节点第0个元素,而不是所有子节点

问题描述

我想在应用程序中使用的用例是,我有一个列表,该列表将有很多孩子,而孩子将有孩子,依此类推。请参考下图。

enter image description here

为了实现这种层次结构,我创建了以下java类

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"}) 
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "ITEM")
public class Item implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @JsonIgnore
    @Column(name = "ID",updatable = false,nullable = false,unique = true)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    
    @Size(max = 500)
    @Column(name = "TYPE",length = 500)
    private String type;
    
    @Column(name = "READONLY")
    private Boolean readOnly;
    
    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY,optional = true)
    @JoinColumn(name = "PARENT")
    private Item parent;
    
    @JsonManagedReference
    @Builder.Default
    @OnetoMany(mappedBy = "parent",cascade = CascadeType.ALL,orphanRemoval=true,fetch = FetchType.LAZY)
    private Set<Item> children = new HashSet<Item>();

}

插入效果很好。但是,当我检索数据时,我不是在Set<Item> children的父节点下获取所有childeren节点,而是仅获取一个childeren节点。集合中的第0个元素。我对这个问题一无所知,我在做什么错。我将得到如下所示的输出

  "items": [
    {
      "id": "1","type": "PARENT 1","parent": null,"readOnly": false,"children": [
        {
          "id": "6","type": "CHILDREN 1","parent": 1,"children": []
        }
      ]
    },{
      "id": "2","type": " PARENT 2","children": []
    },{
      "id": "3","type": " PARENT 3",{
      "id": "4","type": " PARENT 4",{
      "id": "5","type": " PARENT 5",{
      "id": "6",{
      "id": "7","children": []
    }
  ]
}

我应该在哪里获得这种输出

  "items": [
    {
      "id": "1","children": []
        },{
          "id": "7","children": []
    }
  ]
}

在第一项中,我应该有2个孩子,但是要有一个孩子元素。

解决方法

您的问题可能与equals类的Item实现有关:您正在使用@EqualsAndHashCode(onlyExplicitlyIncluded = true)来指示Lombok仅将您希望的字段或方法包括在{{1 }}实现,但您没有使用equals注释任何字段或方法。请参阅relevant docs

由于这个原因,Lombok可能正在生成@EqualsAndHashCode.Include实现,该实现源自每个equals被认为彼此相等,因此Item children仅包含有关首先添加Set

请用Item注释您认为合适的字段,我认为它可以解决问题。例如:

@EqualsAndHashCode.Include