gpt4 book ai didi

java - hibernate 多个 @OneToMany 关系在父关系中生成更多结果

转载 作者:行者123 更新时间:2023-11-30 01:46:41 25 4
gpt4 key购买 nike

我将从结果开始。在下一张图片中,我显示了 company.userAccount 的结果内容。在数据库中,我只有两家公司分配给同一用户,并且 7 项服务附加给其中一家公司。

enter image description here

@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;

}


@Transactional
public 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);
}

@Transactional
public 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; 

这将生成

enter image description here

预期结果:我预计在 UserAccount 中只能看到 2 家公司,而其中一家公司有 6 项服务。为什么我会得到这个结果?为什么同一公司对象多次出现在列表中?我怎样才能避免这种情况?

我相信一种解决方案是将 @OneToMany 关系的获取类型更改为 LAZY(因为它们是默认的)(已经测试了此解决方案并且它有效),但是如果我需要这种类型的场景该怎么办?

最佳答案

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

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

更多信息您可以引用this来源。

关于java - hibernate 多个 @OneToMany 关系在父关系中生成更多结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57685782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com