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

q43xntqr  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(381)

我有三个数据库表组成多对多关系。这些表名为disposition、disposition\u filter和dispositions\u disposition\u filter。前面提到过,disposition\u disposition\u 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;
}

当我在调试器中运行代码并请求从数据库中检索所有disposition filter对象时,我可以看到disposition对象上的filters成员返回为空,尽管该关系中确实存在数据。如果有人知道为什么那张单子空空如也,能给我指出正确的方向,我将不胜感激。

jfewjypa

jfewjypa1#

正如您在第二次更新中意识到的,第一个问题与您配置 dispositions 关系 DispositionFilterEntity ,您交换了 joinColumns 以及 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;

我认为fetch类型与这个问题无关,尽管延迟地获取集合总是明智的。
现在,您将面临堆栈溢出错误。
此错误的原因是您正在以循环方式同时解析这两个关系。
我的意思是,比如说,你拿了一个 DispositionFilterEntity 从数据库。
在您的代码中,您正在解决与 dispositions ,通过调用 getDispositions 在您的代码中,或者隐式地,通过其他方式-我们稍后将看到这种情况。
DispositionEntity 已获取,您正在解决与的关系 filters ,或者显式地调用 getFilters 在代码中,或通过其他方式隐式地。
正如在不同的注解中所指出的,您得到的第一个堆栈溢出是由 toString ,和 equals 以及 hashCode 你的实体。在实体中实现这些方法时不包含任何关系字段始终是一个好的做法,以避免延迟初始化或其他类似于您所面临的问题
在使用lombok时,为了防止出现错误,需要对 dispositions 字段输入 DispositionFilterEntity@ToString.Exclude@EqualsAndHashCode.Exclude .
此外,还可以使用与 filters 字段输入 DispositionEntity .
一旦这个问题得到解决,您将面临一个新的堆栈溢出错误。这一次错误是由您用于将实体转换为DTO的逻辑引起的。
您正在为此目的使用mapstruct。
首先,提供的堆栈跟踪(尽管您稍后提供的源代码不包括最初指定的所有方法)显示了与不同实体DTO对的转换相关的方法。我觉得最好用一个 Mapper 对每个实体数据进行配对。
回到堆栈溢出错误,您必须避免的一个选项是忽略其中一个字段 dispositions 或者 filters ,在相应的Map方法中通过提供相应的 @Mapping 注解:它们中的哪一个,将取决于您的实际用例。
注解正确的mapper方法很重要,在本例中,是将每个实体Map到相应dto的方法,而不是相反的方法。
我最初建议您注意json序列化,apply@jsonignore或任何您需要的防止错误的方法,但可能由于您已经有了dto,因此不再需要它。
当然,如果您不需要关系是双向的,一种可能的解决方案是删除关系的一侧。为什么 filters 字段没有为您提供任何结果是因为您再次交换了 joinColumns 以及 inverseJoinColumns . 而不是这样:

@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 引用要与集合另一侧中适用的实体联接的列。

相关问题