sso*_*m07 2 java sql hibernate duplicates
我已经用@OneToMany 列表映射了一个 1:N 关系,但是当我访问该列表时,由于 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>();
Run Code Online (Sandbox Code Playgroud)
当我使用 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=?
Run Code Online (Sandbox Code Playgroud)
有没有不将 List 转换为 Set 的解决方案?我需要使用 prog.getGames() 获取游戏,不能使用自定义 HQL 或 Criteria。
虽然使用从Set<>根本上解决了您的问题,但我认为这只是获得您所追求的预期结果的创可贴,但它在技术上并没有解决根本问题。
您最终应该使用默认的延迟获取策略,因为我认为急切加载任何关联,尤其是基于集合的关联,都是特定于查询的,因此在构建特定查询时应该切换,而不是作为一部分受到影响您正在执行的实体映射模型。
考虑将来添加新查询但您只对聚合根实体中的属性感兴趣。您的映射模型仍然会急切地获取这些关联,您将通过拥有更大的持久性上下文来消耗额外的资源,这意味着更多的内存消耗并为您不打算使用的东西强加不必要的数据库连接。
如果有多个系列需要补水,我会建议您考虑使用FetchMode.SUBSELECT。
如果我们假设您的查询返回了 10 个实体,则具有 2 个集合的默认惰性策略将发出 21 个查询(1 个用于基本结果集,2 个用于每个加载的实体)。
这样做的好处SUBSELECT是 Hibernate 实际上只会发出 3 个查询(1 个用于基本结果集,每个集合 1 个用于加载所有实体的所有集合元素)。很明显,根据某些查询,将一个带有左连接的查询分解为 3 个查询实际上也可以在数据库级别上表现得更好。
| 归档时间: |
|
| 查看次数: |
3057 次 |
| 最近记录: |