Получить запись с max id, используя критерии гибернации

используя спящий режим ' s критерии API, Я хочу выбрать записи в таблице с максимальным значением для данного столбца.

Я пытался использовать прогнозы, создание псевдонима на max(colunName), затем, используя его в restrictions.eq(), но он продолжает говорить мне "недействительным номером".

Как правильно это сделать с Hibernate?

8 ответов


можно использовать DetachedCriteria чтобы выразить подзапрос, что-то вроде этого:

DetachedCriteria maxId = DetachedCriteria.forClass(Foo.class)
    .setProjection( Projections.max("id") );
session.createCriteria(Foo.class)
    .add( Property.forName("id").eq(maxId) )
    .list();

ссылки


я обнаружил, что с помощью addOrder и setMaxResults вместе работали на меня.

Criteria c = session.createCriteria(Thingy.class);
c.addOrder(Order.desc("id"));
c.setMaxResults(1);
return (Thingy)c.uniqueResult();

используя диалект MySQL, это генерирует подготовленный SQL-оператор примерно так (вырезание некоторых полей):

select this_.id ... from Thingy this_ order by this_.id desc limit ?

Я не уверен, что это решение будет эффективным для диалектов, отличных от MySQL.


использовать

addOrder(Order.desc("id"))

и получить только первый результат:)


бумага HQL:

from Person where person.id = (select max(id) from Person)

непроверенными. Ваша база данных должна понимать подзапросы в предложении where.

слишком ленив, чтобы узнать, может ли/как такой подселект быть выражен с помощью API критериев. Конечно, вы можете выполнить два запроса: сначала получить max id, затем сущность с этим id.


чистое решение также будет :

DetachedCriteria criteria = DetachedCriteria.forClass(Foo.class).setProjection(Projections.max("id"));
Foo fooObj =(Foo) criteria.getExecutableCriteria(getCurrentSession()).list().get(0);

    Date maxDateFromDB = null;
    Session session = (Session) entityManager.getDelegate();
//Register is and Entity and assume maxDateFromDB is a column.
//Status is another entity with Enum Applied.
//Code is the Parameter for One to One Relation between Register and Profile entity.
    Criteria criteria = session.createCriteria(Register.class).setProjection(Projections.max("maxDateFromDB") )
    .add(Restrictions.eq("status.id", Status.Name.APPLIED.instance().getId()));
    if(code != null && code > 0) {
        criteria.add(Restrictions.eq("profile.id", code));
    }
    List<Date> list = criteria.list();

    if(!CollectionUtils.isEmpty(list)){
        maxDateFromDB = list.get(0);
    }

чтобы сделать это полностью с отсоединенными критериями (потому что мне нравится строить отсоединенные критерии без сеанса)

DetachedCriteria maxQuery = DetachedCriteria.forClass(Foo.class)
    .setProjection( Projections.max("id") );
DetachedCriteria recordQuery = DetachedCriteria.forClass(Foo.class)
    .add(Property.forName("id").eq(maxId) );

на max() функция в спящем режиме:

criteria.setProjection(Projections.max("e.encounterId"));