ここで、アイテムの重複や抑制の問題を発生させることなく、通常のクエリとページ付けの方法を使用できる別の解決策について説明します。
このソリューションには、次のような進歩があります。
- この記事で言及されているPKIDソリューションよりも高速です
- 順序を保持し、PKのおそらく大きなデータセットで「in句」を使用しないでください
完全な記事は私のブログで見つけることができます
Hibernateを使用すると、設計時だけでなく、実行時にクエリ実行によってアソシエーションフェッチメソッドを定義できます。したがって、このアプローチを単純なリフレクションと組み合わせて使用し、コレクションプロパティに対してのみクエリプロパティフェッチアルゴリズムを変更するプロセスを自動化することもできます。
まず、エンティティクラスのすべてのコレクションプロパティを解決するメソッドを作成します。
public static List<String> resolveCollectionProperties(Class<?> type) {
List<String> ret = new ArrayList<String>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(type);
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
if (Collection.class.isAssignableFrom(pd.getPropertyType()))
ret.add(pd.getName());
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
return ret;
}
その後、この小さなヘルパーメソッドを使用して、条件オブジェクトにそのクエリでFetchModeをSELECTに変更するようにアドバイスします。
Criteria criteria = …
// … add your expression here …
// set fetchmode for every Collection Property to SELECT
for (String property : ReflectUtil.resolveCollectionProperties(YourEntity.class)) {
criteria.setFetchMode(property, org.hibernate.FetchMode.SELECT);
}
criteria.setFirstResult(firstResult);
criteria.setMaxResults(maxResults);
criteria.list();
これを行うことは、設計時にエンティティのFetchModeを定義することとは異なります。したがって、UIのページングアルゴリズムで通常の結合関連付けフェッチを使用できます。これは、ほとんどの場合、重要な部分ではなく、結果をできるだけ早く取得することがより重要であるためです。