我将从结果开始。在下一张图片中,我将显示 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 行,并且PersistenceBag
hibernate 使用的查询默认情况下不会删除重复项。传递distinct
给你的 sql 是行不通的,因为只有一个父实体。
但这可以通过使用hibernate的查询提示来实现。传递QueryHints.HINT_PASS_DISTINCT_THROUGH
给 yourQuery
只是删除重复的子项。
添加回答
举报
0/150
提交
取消