我有三个构成多对多关系的数据库表。这些表分别命名为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;
}
当我在调试器中运行代码并请求从数据库中检索所有处置过滤器对象时,尽管数据确实确实存在该关系,但我可以看到处置对象上的过滤器成员返回为空。如果有人知道为什么该列表重新变空并且可以指出正确的方向,我将非常感激。
正如您在第二次更新中意识到的那样,第一个问题与中配置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;
我认为获取类型与问题无关,尽管总是建议您延迟获取集合。
现在,您面临着堆栈溢出错误。
导致此错误的原因是您正在以循环方式同时解决这两个关系。
我的意思是说,例如,您正在DispositionFilterEntity
从数据库中获取a 。
在您的代码中,您正在dispositions
通过调用getDispositions
代码来显式地解决与的关系,或者通过其他方式来隐式地解决了这种关系-我们将在以后看到这种情况。
对于每个DispositionEntity
提取的内容,您都将filters
通过调用getFilters
代码来显式地解决,或者通过其他方式隐式地解决的关系。
如不同注释中所述,您第一次堆栈溢出是由toString
和equals
以及hashCode
您的实体的实现引起的。最好在实体的这些方法的实现中不要包含任何关系字段,以避免延迟初始化或其他问题(例如您面临的问题)
就您使用的Lombok而言,为了防止错误,您需要使用和注释dispositions
字段。DispositionFilterEntity
@ToString.Exclude
@EqualsAndHashCode.Exclude
此外,您也可以用相同的方式注释中的filters
字段DispositionEntity
。
解决此问题后,您将面临新的堆栈溢出错误。这次错误是由您用于将实体转换为DTO的逻辑引起的。
您正在为此目的使用Mapstruct。
首先,所提供的堆栈跟踪(尽管您稍后提供的源代码并不包括最初指示的所有方法)显示了与不同实体DTO对的转换相关的方法。我认为Mapper
对每个实体-DTO对使用一个总是更好。
回到堆栈溢出错误,您需要避免的一种选择是通过提供相应的注释来忽略相应映射方法中的dispositions
或字段之一:其中哪个取决于您的实际用例。filters
@Mapping
注释正确的映射器方法很重要,在这种情况下,应将每个实体映射到相应的DTO,而不是相反。
我最初建议您通过应用@JsonIgnore或任何需要防止该错误的方法来进行JSON序列化,但由于您已经拥有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
引用列将与适用于集合另一侧的实体结合在一起。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句