我有一些问题与JPA(Hibernate)和lazy抓取
我有一些实体:任务,奖励,合同关系(都是Lazy):
- 任务One2Many奖励;任务多对多合同;
- 合同One2Many奖励;合约多对多任务;
- 奖励多人查询;奖励多合一合同;
DB包含以下数据:
查询1有Reward1, Reward2和Contract1, Contract2;在某些情况下,我需要带有奖励的任务& &;合同,所以我在jprepository:
@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)
为什么?为什么我有复制?
这就是Hibernate工作的本质。它不会删除由LEFT OUTER JOINS生成的副本。你可以显式指定你需要不同的结果
例如,如果你使用条件来获取数据,你可以指定
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
查看获取数据时生成的SQL。下面是一个常见问题解答,它解释了为什么Hibernate会这样做
同样在第一个查询中,你在同一个SQL中加载多个集合(奖励和合同),这可能导致笛卡尔积。Hibernate有一个Futures API,它可以使用比生成笛卡尔式产品更简单的sql来加载多个子集合。(我不确定期货是否会与JPA一起工作)
一个表可能比另一个表有更多的行。所以给一些条件来避免重复。