0

我在使用 JPA(Hibernate) 和 LazyFetching 时遇到了一些麻烦

我有一些实体:任务、奖励、合同

关系(都是懒惰的):

  • Quest One2Many 奖励;Quest Many2Many 合约;
  • 合约 One2Many 奖励;合同Many2Many任务;
  • 奖励Many2One查询;奖励Many2One合约;

DB 包含这些数据:Quest1 有 Reward1、Reward2 和 Contract1、Contract2;

在某些情况下,我需要 Quest 及其奖励和合同,所以我在 JPArepository 中这样做:

@Query("select Q from Quest Q left join fetch Q.rewards left join fetch Q.contracts")
List<Quest> getAllQuestsWithRewardsAndContracts();

问题是我收到了
一个带有 4 个(但它只有 2 个)奖励(Reward1,Reward2,Reward1,Reward2)和两个合同的任务。
我得到重复的奖励!
我不明白为什么!
如果我这样做:

@Query("select distinct Q from Quest Q left join fetch Q.rewards")
List<Quest> getAllQuestsWithRewardsRew();

我收到一个任务有两个奖励(Reward1,Reward2)

为什么 ?为什么我有重复?

4

2 回答 2

5

这就是 Hibernate 工作的本质。它不会删除由 LEFT OUTER JOINS 生成的重复项。您可以明确指定您需要不同的结果

例如,如果您使用标准来获取数据,您可以指定

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

查看获取数据时生成的 SQL。这是一个常见问题解答,它解释了为什么 Hibernate 会以这种方式运行。

同样在第一个查询中,您正在同一 SQL 中加载多个集合(奖励和合同),这可能会导致笛卡尔积。Hibernate 有一个Futures API,它使用比生成笛卡尔积的 SQL 更简单的 SQL 来帮助加载多个子集合。(我不确定 Futures 是否可以与 JPA 一起使用)

于 2012-12-27T16:35:13.883 回答
0

一个表的行数可能比另一个表多。所以给一些条件以避免重复......

于 2012-12-27T14:52:26.497 回答