JPQLでLIMIT句の代替を考える

JPQLで、あるコメントの最新の情報1件のみを取得したくてSQLを参考に下記のクエリを書いてみたがエラーが発生した。

// model
@Table(name = "approvals")
@NamedQueries({
    @NamedQuery(name = "getLatestApproval", query = "SELECT a FROM Approval AS a WHERE a.report = :report ORDER BY a.id DESC LIMIT 1")
})
- The order by item is not a valid expression.
- The identification variable 'LIMIT' is not defined in the FROM clause.
- The ORDER BY clause has 'a.id DESC ' and 'LIMIT 1' that are not separated by a 
	 comma.

エラー内容から察するにJPQLではLIMITをサポートしていないようである。なので代わりにgetSingleResult()をセットしてみた。

// model
@Table(name = "approvals")
@NamedQueries({
    @NamedQuery(name = "getLatestApproval", query = "SELECT a FROM Approval AS a WHERE a.report = :report ORDER BY a.id DESC")
})

// controller
Approval getLatestApproval = em.createNamedQuery("getLatestApproval", Approval.class)
    .setParameter("report", r)
    .setMaxResults(1)
    .getSingleResult();

そうすれば降順で得た新着順の日報からSingleResult、つまり1つだけの結果を取得できる。もし、最新の結果2つを取得したい場合はリストを使う必要がある。

List<Approval> getLatestApproval = em.createNamedQuery("getLatestApproval", Approval.class)
    .setParameter("report", r)
    .setMaxResults(2)
    .getResultList();

ここで重要なのはsetMaxResults(int)のintを任意の数字に変更してあげることである。もしオフセットを利用したければsetFirstResult(int)を指定すればOK。

To comment

@TOC
閉じる