簡體   English   中英

從數據庫返回的對象列表為空

[英]List on object returned from database empty

我有三個構成多對多關系的數據庫表。 這些表被命名為 Disposition、Disposition_Filter 和 Dispositions_Disposition_Filter。 已經提到過, Disposition_Disposition_Filter 是“連接表”。

類 DispositionFilterEntity 如下所示:

@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "disposition_filter")
public class DispositionFilterEntity {
  @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
  @GeneratedValue(generator = "uuid2")
  @Id
  private String id;

  @Column private String name;
}

雖然 DispositionEntity 類看起來像這樣:

@Getter
@Setter
@ToString
@EqualsAndHashCode
@Entity(name = "dispositions")
public class DispositionEntity {
  @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
  @GeneratedValue(generator = "uuid2")
  @Id
  private String id;

  /** @see Disposition */
  @Column(nullable = false)
  private String name;

  @Column(nullable = false)
  private String description;

  @Column(nullable = false)
  private String category;

  @Column private boolean active;

  @Column private String label;

  @Column(name = "hidden_if_agent_not_assigned")
  private Boolean hidden;

  @Transient
  public Disposition getAttributeTypeEnum() {
    return Disposition.from(name);
  }

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(
    name = "dispositions_disposition_filter",
    joinColumns = {@JoinColumn(name = "filter_id")},
    inverseJoinColumns = {@JoinColumn(name = "disposition_id")})
  private List<DispositionFilterEntity> filters;
}

當我在調試器中運行我的代碼並請求從數據庫中檢索所有處置過濾器對象時,我可以看到處置對象上的過濾器成員返回空,盡管該關系中確實存在數據。 如果有人知道為什么該列表是空的並且可以為我指明正確的方向,我將不勝感激。

正如您在第二次更新中意識到的那樣,您的第一個問題與您在DispositionFilterEntity配置dispositions關系的dispositions有關,您交換了joinColumnsinverseJoinColumns屬性中列的名稱。 取而代之的是:

@ManyToMany
@JoinTable(
  name = "dispositions_disposition_filter",
  joinColumns = {@JoinColumn(name = "disposition_id")},
  inverseJoinColumns = {@JoinColumn(name = "filter_id")})
private List<DispositionEntity> dispositions;

你需要:

@ManyToMany
@JoinTable(
  name = "dispositions_disposition_filter",
  joinColumns = {@JoinColumn(name = "filter_id")},
  inverseJoinColumns = {@JoinColumn(name = "disposition_id")})
private List<DispositionEntity> dispositions;

我認為獲取類型與問題無關,盡管總是建議懶惰地獲取集合。

現在,您正面臨堆棧溢出錯誤。

此錯誤的原因是您正在以循環方式同時解決兩個關系。

我的意思是,例如,您正在從數據庫中獲取一個DispositionFilterEntity

在您的代碼中,您正在通過在代碼中調用getDispositions顯式地或通過其他方式隱式地解決與dispositions的關系 - 我們稍后將看到情況就是如此。

對於獲取的每個DispositionEntity ,您再次通過在代碼中調用getFilters顯式地或通過其他方式隱式地解析與filters的關系。

正如不同評論中所指出的,您獲得的第一個堆棧溢出是由實體的toStringequalshashCode的實現引起的。 在實體中的這些方法的實現中不包含任何關系字段始終是一個好習慣,以避免延遲初始化或其他問題,例如您面臨的問題

就您使用 Lombok 而言,為了防止出現錯誤,您需要使用@ToString.Exclude@EqualsAndHashCode.Exclude注釋DispositionFilterEntitydispositions字段。

此外,您還可以以相同的方式注釋DispositionEntityfilters字段。

一旦這個問題得到解決,你就會面臨一個新的堆棧溢出錯誤。 這次錯誤是由您用於將實體轉換為 DTO 的邏輯引起的。

您正在為此目的使用 Mapstruct。

首先,提供的堆棧跟蹤 - 盡管您稍后提供的源代碼不包括最初指出的所有方法 - 顯示了與不同實體-DTO 對的轉換相關的方法。 我認為為每個實體-DTO 對使用一個Mapper總是更好。

回到堆棧溢出錯誤,您必須避免的一種選擇是通過提供相應的@Mapping注釋來忽略相應映射方法中的一個字段,無論是dispositions還是filters :它們中的哪一個,這將取決於您的實際用例。

注釋正確的映射器方法很重要,在這種情況下,將每個實體映射到相應的 DTO 的方法,而不是相反。

我最初建議您處理 JSON 序列化,應用 @JsonIgnore 或任何您需要防止錯誤的方法,但可能由於您已經有了 DTO,將不再需要它。

當然,如果您不需要關系是雙向的,一種可能的解決方案是刪除關系的一側。 filters字段沒有為您提供任何結果的原因是因為您再次交換了joinColumnsinverseJoinColumns的值。 取而代之的是:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
  name = "dispositions_disposition_filter",
  joinColumns = {@JoinColumn(name = "filter_id")},
  inverseJoinColumns = {@JoinColumn(name = "disposition_id")})
private List<DispositionFilterEntity> filters;

你需要:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
  name = "dispositions_disposition_filter",
  joinColumns = {@JoinColumn(name = "disposition_id")},
  inverseJoinColumns = {@JoinColumn(name = "filter_id")})
private List<DispositionFilterEntity> filters;

請始終記住inverseJoinColumns引用要與集合另一側適用的實體連接的列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM