Hibernate OneToMany 列表中的重复结果

2024-05-01

我已将 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 个查询实际上也可以在数据库级别执行得更好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate OneToMany 列表中的重复结果 的相关文章

随机推荐