gpt4 book ai didi

java - Hibernate OneToMany 列表中的重复结果

转载 作者:行者123 更新时间:2023-12-02 13:11:17 25 4
gpt4 key购买 nike

我已将 1:N 关系与 @OneToMany 列表映射,但当我访问该列表时,由于 OUTER JOIN,结果会重复。映射如下所示:

@Entity
public class Programmer

@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="emails", joinColumns=@JoinColumn(name="id", nullable=false))
@Column(name="email", nullable=false)
protected Set<String> emails = new HashSet<String>();

@OneToMany(mappedBy="programmer", fetch=FetchType.EAGER)
private List <Game> games = new ArrayList<Game>();

当我使用 prog.getGames() 获取属性时,结果会重复,因为 Hibernate SQL 进行了 OUTER JOIN:

from programmer 
left outer join emails on programmer.id=emails.id
left outer join game on programmer.id=game.id
where programmer.id=?

有没有不用将List转成Set的解决方案?我需要使用 prog.getGames() 获取游戏,无法使用自定义 HQL 或 Criteria。

最佳答案

同时使用Set<>从根本上解决您的问题,我认为这只是一个创可贴,以获得您所追求的预期结果,但它并没有从技术上解决根本问题。

您最终应该使用默认的延迟获取策略,因为我认为急切加载任何关联,特别是基于集合的关联,都是特定于查询的,因此应该在构建特定查询时切换并且不受影响作为您正在做的实体映射模型的一部分。

考虑将来您添加新查询,但您只对聚合根实体中的属性感兴趣。您的映射模型仍然会强制急切地获取这些关联,您将通过拥有更大的持久性上下文来消耗额外的资源,这意味着更多的内存消耗,并对您不打算使用的东西强加不必要的数据库连接。

如果您需要水合多个集合,我建议您考虑使用FetchMode.SUBSELECT反而。

如果我们假设您的查询返回 10 个实体,则具有 2 个集合的默认惰性策略将发出 21 个查询(1 个用于基本结果集,2 个用于每个加载的实体)。

SUBSELECT的好处是 Hibernate 实际上只会发出 3 个查询(1 个用于基本结果集,1 个用于每个集合,以加载所有实体的所有集合元素)。显然,根据某些查询,将一个带有左连接的查询分解为 3 个查询实际上也可以在数据库级别执行得更好。

关于java - Hibernate OneToMany 列表中的重复结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43941363/

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