この回答https://stackoverflow.com/a/2111420/3989524に基づいて、最初に動作する SQL を作成しました。
SELECT d.*
FROM device d
LEFT OUTER JOIN installation_record ir1 ON (d.id = ir1.device)
LEFT OUTER JOIN installation_record ir2 ON (d.id = ir2.device AND ir1.install_date < ir2.install_date)
WHERE ir2.id IS NULL AND ir1.uninstall_date IS NULL;
次に、(最終的に) 同等の HQL を生成するように見える基準クエリですが、Hibernate はエラーをスローします。
org.hibernate.hql.internal.ast.QuerySyntaxException: with-clause が 2 つの異なる from-clause 要素を参照しました
エラー メッセージの HQL:
SELECT generatedAlias0 FROM Device AS generatedAlias0
LEFT JOIN generatedAlias0.installationRecordList AS generatedAlias1
LEFT JOIN generatedAlias0.installationRecordList AS generatedAlias2
WITH generatedAlias1.installDate<generatedAlias2.installDate
WHERE ( generatedAlias2.id IS NULL ) AND ( generatedAlias1.uninstallDate IS NULL )
条件クエリ:
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Device> cq = cb.createQuery(Device.class);
final Root<Device> root = cq.from(Device.class);
final Join<Device, InstallationRecord> join1 = root.join(Device_.installationRecordList, JoinType.LEFT);
final Join<Device, InstallationRecord> join2 = root.join(Device_.installationRecordList, JoinType.LEFT);
join2.on(cb.lessThan(join1.get(InstallationRecord_.installDate), join2.get(InstallationRecord_.installDate)));
cq.select(root);
final List<Predicate> predicates = Lists.newArrayList();
predicates.add(cb.isNull(join2.get(InstallationRecord_.id)));
predicates.add(cb.isNull(join1.get(InstallationRecord_.uninstallDate)));
cq.where(predicates.toArray(new Predicate[] {}));
return em.createQuery(cq).getResultList();
とにかく欲しいものを手に入れる方法はありますか、それとも内部の休止状態のバグを回避する方法は他にありません。