HibernateでCriteriaオブジェクトを再利用するには?
-
21-08-2019 - |
質問
私は休止状態とdisplaytagでクエリ結果のページネーションを行うと、DetachedCriteria
オブジェクトが邪魔にするために最善をやっている休止しようとしています。私に説明してみましょう...
displaytagで改ページを行う最も簡単な方法は、以下の方法、とりわけ、持っていPaginatedList
インタフェースを実装しているように見えるます:
/* Gets the total number of results. */
int getFullListSize();
/* Gets the current page of results. */
List getList();
/* Gets the page size. */
int getObjectsPerPage();
/* Gets the current page number. */
int getPageNumber();
/* Get the sorting column and direction */
String getSortCriterion();
SortOrderEnum getSortDirection();
私は私のPaginatedList実装Criteriaオブジェクトを投げることを考えて、それがtheese線に沿って作業しましょうよ...
getFullListSize() {
criteria.setProjection(Projections.rowCount());
return ((Long) criteria.uniqueResult()).intValue();
}
getList() {
if (getSortDirection() == SortOrderEnum.ASCENDING) {
criteria.addOrder(Order.asc(getSortCriterion());
} else if (getSortDirection() == SortOrderEnum.DECENDING) {
criteria.addOrder(Order.desc(getSortCriterion());
}
return criteria.list((getPageNumber() - 1) * getObjectsPerPage(),
getObjectsPerPage());
}
しかし、これは動作しません、addOrder()
またはsetProjection()
呼び出しが基準を修正するためには、連続して呼び出すために利用可能な、それをレンダリングするオブジェクト。私は、呼び出しの順序の完全わからないんだけど、デシベルは明らかに間違っている「getFullListSize()
」をやろうとしselect count(*) ... order by ...
にエラーがスローされます。
私は、クエリ条件を追跡するために私自身のオブジェクトを作成し、各呼び出しのためにCriteriaオブジェクトを再構築することによって、これを修正することができると思うが、それはまた別の車輪の再発明のように感じています。よりスマートな方法は、おそらく最初に渡された基準をコピーし、そのコピーで作業し、ありますか?
の のアップデートのの:
すぐに渡された順序がありますよう、getList
が最初に呼び出されたように見え、そしてgetFullListSize
は後に複数回呼び出されるので、getFullListSize
は失敗します。それは(私が言うと思いますgetList
に)一度だけデシベルを打つために意味をなすとCriteria
オブジェクトをリセット/コピーする必要はありませんし、結果をキャッシュだろうが、まだ...
の の更新(再)のの:
私はcount
を行うことはできませんselect
、およびその逆をやった後は、そのことを忘れます。私は実際には2つの異なるCriteria
オブジェクトを必要とします。
解決
だけでなく、DetachedCriteriaをはSerializableですので、あなたが組み込まれてい(無粋場合)深いクローンのサポートを。あなたは、あなたがそれを使用するたびに、それをデシリアライズ、[]一度構築のバイトに最初の基準をシリアル化できます。
他のヒント
Criteria.setProjection(null);
Criteria.setResultTransformer(Criteria.ROOT_ENTITY);
有効行数突起と基準自体の実行との間の基準を「リセット」します。
私はあなたの注文はをrowCountを行う前に、それは物事を遅くます追加されていないことを確認します。 PaginatedListの私の実装は、常に結果を探して前にカウントクエリを実行し、その順序は問題ではありません。
<のhref = "http://weblogs.asp.net/stefansedich/archive/2008/10/03/paging-with-nhibernate-using-a-custom-extension-method-to-make-it- easier.aspx」のrel = "nofollowをnoreferrer"> http://weblogs.asp.net/stefansedich/archive/2008/10/03/paging-with-nhibernate-using-a-custom-extension-method-to-make -it-easier.aspxする
その記事では、私はCriteriaTransformer.clone方法を見つけます。
これは、基準オブジェクトをコピーする必要があります。
また、あなたのGETLIST法上の投影を設定することができます。
Woops私はあなたがJavaの休止状態としていたのに気づきませんでした。とにかく、この http://forum.hibernate.org/viewtopic.php?t=939039 の
フォーラムのポストは、あなたの質問に答えることができる必要があります。
醜いです。私はちょうどDetachedCriteria
オブジェクトおよびデシリアライズ必要なときにそれを建設上のバイト配列にPaginatedList
オブジェクトをシリアル化。痛います。
試してみる価値もう一つます:
ような一般的なDAOの実装1は、Hibernateのサイトの上で提案してPaginatedListに渡します制限オブジェクトとともにオブジェクト、。 PaginatedListオブジェクトは、
のような何かをするだろうCriteria.forClass(myDAO.getPersistentClass())
.add(myRestrictions)
.addOrder(<someOrder>)
と
Criteria.forClass(myDAO.getPersistentClass())
.add(myRestrictions)
.setProjection(Projections.rowCount());
は、まだことを試していないが、それが動作するはずです。
public static DetachedCriteria Clone(this DetachedCriteria criteria)
{
var dummy = criteria.ToByteArray();
return dummy.FromByteArray<DetachedCriteria>();
}