Kim*_*m L 14 java hibernate criteria hibernate-criteria
这怎么可能,我必须遵循标准
Criteria criteria = getSession().createCriteria(c);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.add(Restrictions.eq("active",true));
List list = criteria.list();
列表的大小现在是20.如果我在条件中添加最大结果,
Criteria criteria = getSession().createCriteria(c);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setMaxResults(90);
criteria.add(Restrictions.eq("active",true));
List list = criteria.list();Run Code Online (Sandbox Code Playgroud)
..现在列表的大小是18!
在定义最大结果后,我不明白结果集大小如何更小,因为行数小于定义的最大值.这肯定看起来像一个bug,或者还有一些我不知道的hibernate奇怪的方面?
如果您正在寻找这个问题的答案,请务必阅读接受的答案及其评论.
通过在Hibernate中打开SQL调试并比较生成的查询,可以非常清楚地看到这里发生的事情.
使用一个相当简单的Sale→ Item一对多映射(希望是不言自明的),Criteria基于a 的查询如下:
Criteria c = sessionFactory.getCurrentSession().createCriteria(Sale.class);
c.createAlias("items", "i");
c.add(Restrictions.eq("i.name", "doll"));
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
c.setMaxResults(2);
Run Code Online (Sandbox Code Playgroud)
像这样产生SQL:
select top ? this_.saleId as saleId1_1_, ...
from Sale this_
inner join Sale_Item items3_ on this_.saleId=items3_.Sale_saleId
inner join Item items1_ on items3_.items_id=items1_.id
where items1_.name=?
Run Code Online (Sandbox Code Playgroud)
而Query像这样:
Query q = sessionFactory.getCurrentSession().createQuery("select distinct s from Sale s join s.items as i where i.name=:name");
q.setParameter("name", "doll");
q.setMaxResults(2);
Run Code Online (Sandbox Code Playgroud)
产生类似的东西:
select top ? distinct hibernated0_.saleId as saleId1_
from Sale hibernated0_
inner join Sale_Item items1_ on hibernated0_.saleId=items1_.Sale_saleId
inner join Item hibernated2_ on items1_.items_id=hibernated2_.id
where hibernated2_.name=?
Run Code Online (Sandbox Code Playgroud)
注意第一行(DISTINCT)中的差异.甲ResultTransformer像DISTINCT_ROOT_ENTITY是一个Java类,该处理SQL行的结果之后被执行的SQL.因此,当您指定a maxResults时,将作为SQL的行限制应用; SQL包含对元素的连接Collection,因此您将SQL结果限制为90 个子元素.一旦DISTINCT_ROOT_ENTITY变压器被施加,可能导致低于20个元素,完全取决于其根元素碰巧第一出来在90接合结果.
DISTINCT在HQL中表现的方式非常不同,因为它实际上使用了SQL DISTINCT关键字,它在行限制之前应用.因此,这表现得如您所愿,并解释了2之间的区别.
理论上你应该考虑在setProjectionSQL级别应用一个投影 - 类似于c.setProjection(Projections.distinct(Projections.rootEntity()))- 但遗憾的Projections.rootEntity()是不存在,我只是编造了它.也许它应该!
| 归档时间: |
|
| 查看次数: |
5432 次 |
| 最近记录: |