Hibernate の Criteria API を使用して、特定の列の最大値を持つテーブル内のレコードを選択します。
max(colunName)
に Projections 、 エイリアスの作成 を使用してから、 restrictions.eq()
で使用しようとしました。 、しかし、「無効な番号」と表示され続けます。
Hibernateでそれを行う正しい方法は何ですか?
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で表現できるかどうか、どのように表現できるかを見つけるのが面倒です。もちろん、2つのクエリを実行できます。最初に最大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);
}
完全にDetached Criteriaでそれを行うには(セッションなしでDetached Criteriaを構築したいので)
DetachedCriteria maxQuery = DetachedCriteria.forClass(Foo.class)
.setProjection( Projections.max("id") );
DetachedCriteria recordQuery = DetachedCriteria.forClass(Foo.class)
.add(Property.forName("id").eq(maxId) );