Получить запись с 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();
ссылки
- Hibernate Core Справочное Руководство
я обнаружил, что с помощью 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.
бумага 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) );