Можно достигнуть желаемого результата путем запроса списка отличных идентификаторов вместо списка отличных гидратировавших объектов.
Просто добавляют это к Вашим критериям:
criteria.setProjection(Projections.distinct(Projections.property("id")));
Теперь Вы получите корректное количество результатов согласно Вашему находящемуся на строке ограничению. Причина это работает, состоит в том, потому что проекция выполнит проверку отчетливости как часть запрос SQL, вместо того, что делает ResultTransformer, который должен отфильтровать результаты для отчетливости после , запрос SQL был выполнен.
Стоящий замечания то, что вместо того, чтобы получить список объектов, Вы теперь получите список идентификаторов, от которых можно использовать для объектов гидрата, в спящем режиме позже.
Я использую этот со своими кодами.
Просто добавьте это к своим критериям:
критериям.setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY );
этот код будет похож на таблицу выбора * из собственного sql. Надеюсь, это поможет.
Решение:
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
работает очень хорошо.
NullPointerException
в некоторых случаях!
Без критериев.setProjection (Projection.distinct (Projection.property ("id")))
все запросы идут хорошо!
Это плохое решение!
Другой способ - использовать SQLQuery. В моем случае следующий код работает нормально:
List result = getSession().createSQLQuery(
"SELECT distinct u.id as usrId, b.currentBillingAccountType as oldUser_type,"
+ " r.accountTypeWhenRegister as newUser_type, count(r.accountTypeWhenRegister) as numOfRegUsers"
+ " FROM recommendations r, users u, billing_accounts b WHERE "
+ " r.user_fk = u.id and"
+ " b.user_fk = u.id and"
+ " r.activated = true and"
+ " r.audit_CD > :monthAgo and"
+ " r.bonusExceeded is null and"
+ " group by u.id, r.accountTypeWhenRegister")
.addScalar("usrId", Hibernate.LONG)
.addScalar("oldUser_type", Hibernate.INTEGER)
.addScalar("newUser_type", Hibernate.INTEGER)
.addScalar("numOfRegUsers", Hibernate.BIG_INTEGER)
.setParameter("monthAgo", monthAgo)
.setMaxResults(20)
.list();
Различие делается в базе данных! В отличие от:
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
где различие выполняется в памяти после загрузки сущностей!