为了账号安全,请及时绑定邮箱和手机立即绑定

休眠多个@OneToMany 关系在父关系中生成更多结果

休眠多个@OneToMany 关系在父关系中生成更多结果

森林海 2023-06-21 13:28:23
我将从结果开始。在下一张图片中,我将显示 company.userAccount 的结果内容。在数据库中,我只有两家公司分配给同一个用户,其中一家公司有 7 项服务。@Entity@Table(name = "user_account")@Data@Introspected@JsonIgnoreProperties(value = {"id"})public class UserAccount {    ...    @OneToMany(mappedBy = "userAccount", fetch = FetchType.EAGER)    private List<Company> companies = new ArrayList<>();}@Entity@Table(name = "company")@Data@Introspected@ToString(exclude = {"userAccount"})@JsonIgnoreProperties(value = {"id", "userAccount"})public class Company {    ...    @ManyToOne(optional = false)    @JoinColumn(name = "user_account_id", updatable = false, nullable = false)    private UserAccount userAccount;}@Entity@Table(name = "service")@Data@Introspected@ToString(exclude = {"company"})@JsonIgnoreProperties(value= {"id", "company"})public class Service {    ...    @ManyToOne(optional = false)    @JoinColumn(name = "company_id", updatable = false, nullable = false)    private Company company;}@Transactionalpublic Service saveService(@Valid @Uuid UUID companyUuid, SaveServiceCommand command) {    Company company = companyRepository.getCompanyByUuid(companyUuid).orElseThrow(() -> new NoSuchElementException("unrecognized company"));    Service service = new Service();    service.setCompany(company);    service.setName(command.getName());    service.setUuid(UUID.randomUUID().toString());    return companyRepository.saveCompanyService(service);}@Transactionalpublic Service saveCompanyService(@Valid Service service) {    entityManager.persist(service);    return service;}生成的查询(简化)是select * from user_account a left outer join company c on a.id=c.user_account_id left outer join service s on c.id=s.company_id; 这将产生预期结果:我期望在 UserAccount 中只看到 2 家公司,其中一家公司有 6 项服务。为什么我会有这个结果?为什么同一个公司对象多次出现在列表中?我怎样才能避免这种情况?我相信一种解决方案是将 @OneToMany 关系的获取类型更改为 LAZY (因为它们是默认的)(已经测试了该解决方案并且它有效),但是如果我需要这种类型的场景怎么办?
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

是的,有两家公司,就像你说的那样。您可以注意到,所有对象都是相同的(哈希值匹配)。其背后的原因是该查询为一家公司生成 6 行,并且PersistenceBaghibernate 使用的查询默认情况下不会删除重复项。传递distinct给你的 sql 是行不通的,因为只有一个父实体。

但这可以通过使用hibernate的查询提示来实现。传递QueryHints.HINT_PASS_DISTINCT_THROUGH给 yourQuery只是删除重复的子项。

查看完整回答
反对 回复 2023-06-21
  • 1 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信