ここで何が起こっているかは、HibernateでSQLデバッグをオンにし、生成されたクエリを比較することで非常に明確に確認できます。
かなり単純なSale
→ Item
1対多のマッピング(うまくいけば自明です)を使用して、次のCriteria
ようなベースのクエリ:
Criteria c = sessionFactory.getCurrentSession().createCriteria(Sale.class);
c.createAlias("items", "i");
c.add(Restrictions.eq("i.name", "doll"));
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
c.setMaxResults(2);
次のようなSQLを生成します。
select top ? this_.saleId as saleId1_1_, ...
from Sale this_
inner join Sale_Item items3_ on this_.saleId=items3_.Sale_saleId
inner join Item items1_ on items3_.items_id=items1_.id
where items1_.name=?
一方、Query
このような:
Query q = sessionFactory.getCurrentSession().createQuery("select distinct s from Sale s join s.items as i where i.name=:name");
q.setParameter("name", "doll");
q.setMaxResults(2);
次のようなものを生成します:
select top ? distinct hibernated0_.saleId as saleId1_
from Sale hibernated0_
inner join Sale_Item items1_ on hibernated0_.saleId=items1_.Sale_saleId
inner join Item hibernated2_ on items1_.items_id=hibernated2_.id
where hibernated2_.name=?
最初の行(DISTINCT
)の違いに注意してください。ResultTransformer
同様に、SQLが実行された後にSQL行の結果を処理するDISTINCT_ROOT_ENTITY
Javaクラスがあります。したがって、を指定すると、SQLの行制限として適用されます。SQLには、の要素への結合が含まれているため、SQLの結果を90個のサブ要素に制限しています。トランスフォーマーが適用されると、ルート要素が20未満になる可能性があります。これは、90の結合された結果で最初に出てくるルート要素に完全に依存します。maxResults
Collection
DISTINCT_ROOT_ENTITY
DISTINCT
HQLでは、行制限の前DISTINCT
に適用されるSQLキーワードを実際に使用するという点で、動作が大きく異なります。したがって、これは期待どおりに動作し、2つの違いを説明します。
理論的にはsetProjection
、SQLレベルでプロジェクションを適用することを検討する必要があります-のようなものc.setProjection(Projections.distinct(Projections.rootEntity()))
-しかし、残念ながらProjections.rootEntity()
存在しないので、私はそれを作り上げました。おそらくそれはすべきです!