我正在尝试使用Hibernate Criteria API来获取数据,在其中构建我的Criteria,我需要对它们进行分页,从而获得所有行的计数。
我面临的问题是,如果我尝试使用以下方法对数据进行计数:
criteria.setProjection(Projections.rowCount());
Integer count = (Integer)criteria.uniqueResult(); // or criteria.list().get(0) = same
对于数据获取,我将这些属性添加到我的条件中
criteria.setProjection(null);
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
/*
* Problematic part, if I do .list() now, I get many more rows fetched
* it's because ROOT_ENTITY has @ManyToMany
*/
List<T> lister = criteria.list();
criteria.setMaxResults(pageable.getPageSize());
criteria.setFirstResult((int) pageable.getOffset());
List<T> list = criteria.list(); // Fetches 10 (or whatever pageSize is)
问题是我的count < lister.size()
,真正的问题来了。
假设我有count = 50
,但是lister.size()
-如果我未应用分页,则为100,例如。我只能将用户的分页呈现为50。
我不能将lister.size()
用作分页的“总数”,因为它获取不必要的数据只是为了对它们进行大小调整。
当我观察到查询时,我的计数查询只是不与该@ManyToMany关联进行JOIN,但是在执行了几行之后,除了setMaxResults和setFirstResult之外,我不应该修改查询。 / p>
我需要的是仅获取表A中的数据,忽略@ManyToMany
关联以仅获得那50行。协会也有FetchType.LAZY
,我什至尝试添加FetchMode.SELECT/SUBSELECT
,这对LAZY来说是不必要的,没有帮助,总是查询条件总是将条件归入表B。
我还尝试了setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
;
但是使用分页,它的工作原理就像“获取数据后的过滤器”一样,因此,如果查询导致前10行只有表A的3个DISTINCT实体,则我的结果列表中只有3个对象。类似于-手动运行查询,它返回:
A.prop1 | B.prop1
XXX | 1
XXX | 2
XXX | 3
YYY | 1
YYY | 2
ZZZ | 1
ZZZ | 2
CCC | 1
CCC | 2
EEE | 1
使用setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
和setMaxResults(5);
-说5(页面大小),即使我的页面需要5个实体,我的列表也只包含2个实体(XXX,YYY)。
那么我需要实现什么。我需要获取表A的不同值的计数(这实际上是我的计数所做的),还需要从获取数据查询中获取不同的值,这很神奇地恰好可以与我的DTO类A拥有的几乎所有内容连接在一起,而无需修改根本不执行任何JOINing的条件。