わかりました。次の(省略形の)3つのエンティティクラスとHibernateUtilクラスがあります。
public class Tag {
@Id
BigDecimal id;
String tag
@ManyToMany( mappedBy="tags" )
List<Label> labels;
}
public class Label {
@Id
BigDecimal id;
String label;
@ManyToMany( targetEntity=Tag.class )
List<Tag> tags;
}
public class Data {
@Id
BigDecimal id;
BigDecimal data;
@ManyToOne
Label label;
}
public class HibernateUtil {
public static List pagedQuery(DetachedCriteria detachedCriteria, Integer start, Integer size) throws WebApplicationException {
Session session = getSession();
try {
Transaction transaction = session.beginTransaction();
List records = detachedCriteria.getExecutableCriteria(session)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.setFirstResult(start)
.setMaxResults(size)
.list();
transaction.commit();
return records;
} catch (Exception e) {
// Place Logger here...
throw new WebApplicationException(e);
} finally {
session.close();
}
}
}
私が抱えている問題は、HibernateUtil.pagedQuery(detatchedCriteria、start、size)を使用してDataクラスをクエリしようとすると、結果リストがsizeパラメーターと一致しないことです。この理由は、hibernateがタグ(Data.Label.Tags)を含めるようにクエリを作成する方法であることがわかりました。
たとえば、ラベルに複数のタグが関連付けられている場合、完全なページ分割クエリで使用されるデータオブジェクトサブクエリの結果リストは次のようになります(これは、Hibernateがコンソールに吐き出すSQLを解析することで見つかりました)
- データ-1;ラベル:タグ-1
- データ-1;ラベル;タグ-2
- データ-2;ラベル;タグ-1
- データ-2;ラベル;タグ-2
- 等...
これをsize=3で呼び出すと、返される結果セットは次のようになります。
- データ-1;ラベル:タグ-1
- データ-1;ラベル;タグ-2
- データ-2;ラベル;タグ-1
ただし、Hibernateは最初の2つの行をグループ化し(同じDataオブジェクトであるため)、返されたListオブジェクトのサイズは2(Data-1とData-2)になります。
setResultTransformerメソッドをGoogleで見つけたProjectionアプローチに置き換えようとしましたが、データオブジェクトのIDしか返されませんでした。
誰かアドバイスはありますか?ここからどこへ行けばいいのかわからない…