繁体   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