从数据库返回的对象列表为空

List on object returned from database empty

我有三个数据库 table,它们构成了多对多关系。 table 被命名为 Disposition、Disposition_Filter 和 Dispositions_Disposition_Filter。话虽如此,Disposition_Disposition_Filter 是“加入 table”。

class 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 class 看起来像这样:

@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 关系的方式有关,您交换了 [=16] 中的列名称=] 和 inverseJoinColumns 属性。而不是这个:

@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

在您的代码中,您正在解决与 dispositions 的关系,可以通过在您的代码中调用 getDispositions 显式地解决,也可以通过其他方式隐式地解决 - 我们稍后会看到是这种情况.

对于每个获取的 DispositionEntity,您正在解决与 filters 的关系,同样,通过在您的代码中调用 getFilters 显式地,或通过其他方式隐式地。

如不同评论中所示,您遇到的第一个堆栈溢出是由实体的 toStringequalshashCode 的实现引起的。在实体中的这些方法的实现中不包含任何关系字段始终是一个好习惯,以避免延迟初始化或其他问题,例如您面临的问题

就您使用的 Lombok 而言,为了防止错误,您需要使用 @ToString.Exclude@EqualsAndHashCode.Exclude 注释 DispositionFilterEntity 中的 dispositions 字段。

另外,DispositionEntity中的filters字段也可以用同样的方式注释。

解决此问题后,您遇到了新的堆栈溢出错误。这次错误是由您用于将实体转换为 DTO 的逻辑引起的。

您正在为此目的使用 Mapstruct。

首先,提供的堆栈跟踪——尽管您稍后提供的源代码不包括最初指出的所有方法——显示了与不同实体-DTO 对的转换相关的方法。我认为对每个实体-DTO 对使用一个 Mapper 总是更好。

回到堆栈溢出错误,您必须避免的一种选择是忽略其中一个字段,即 dispositionsfilters,在相应的映射方法中通过提供相应的 @Mapping注解:具体是哪一个,要看你的实际用例了。

注释正确的映射器方法很重要,在本例中,是将每个实体映射到相应 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 引用的列与适用于集合另一端的实体相连接。