java - Criteria API returns a too small resultset -
How is this possible, I have to follow the criteria
criteria = getSession () .createCriteria (c); Criteria.setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY); Criteria.add (restrictions.eq ("active", true)); List list = criteria List ();
Now the size of the list is 20. If I add the maximum results to the criteria,
Criterion Criteria = GetSession (). CreateCriteria (c); Criteria.setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY); Criterion. Setmax result (90); Criteria. Add (restriction.ec ("active", true)); List list = criteria List ();
.. Now the size of the list is 18!
I do not understand how much the smallest result may be after defining the size of the results, because the amount of rows defined is smaller than the maximum. It definitely looks like a bug, or again some strange aspects are brought to hibernation that I do not know?
If you are looking for an answer to this question, make sure that the acceptable answer and its comments.
What's happening here, can be seen very clearly by turning on SQL debugging in hibernate And compare the generated queries.
Using a very simple sales
→ item
One-to-many mapping (which is expected to be self explanatory), a Criteria
based query like this:.
Criterion c = sessionFactory.getCurrentSession () createCriteria (Sale.class); C.createAlias ("item", "I"); C.add (ban.eq ("i.name", "doll")); C.setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY); C.setMaxResults (2);
Generates SQLs like this:
Choose Top? SaleId1_1_size this_.saleId, ... joining this_interpret from saleItem_ items item_III_III_III_III_III items_III_III_III Item items_3_.Sale_saleId item items1_ items3_.items_id = items1_.id where items1_.name =?
While a query
like this:
query q = sessionFactory.getCurrentSession () createQuery (select "From" Q.setParameter ("name", "doll"); q.setMaxResults (2);
as is where i.name =: "name"); as sales join s.items.
produces something like this:
select from top? Sale from saleId1_ as specific hibernated0_.saleId join in inner Sale_Item items1_ hibernated0_.saleId = items1_ Items in the Sale_saleId inner join hibernated2_ on items1_.items_id = hibernated2_.id where hibernated2_.name = hibernat Ed0_?
Note the difference in the very first row ( DISTINCT
). ResultTransformer
as DISTINCT_ROOT_ENTITY
Java class, which processes the results of SQL rows followed by SQL is executed. Therefore, when you specify maxResults
Will be implemented in the form; Contains elements included in the archive
in SQL, so you are limiting your SQL results to 90 sub-element Once DISTINCT_ROOT_ENTITY
Transformer is applied, which can result in less than 20 basic elements, are purely dependent on which the results in the original element 90 come first.
Difference in HQL
behaves differently, actually uses that SQL DISTINCT
, before the row limit Has been implemented Therefore, it behaves according to your expectations, and tells the difference between 2.
In theory, you should consider setProjection
to apply a projection at the SQL level - something like this c.setProjection (Projections.distinct (Projections.distinct () ))
- But unfortunately does not exist Projections.rootEntity ()
, I just made it up. Maybe it should be!
Comments
Post a Comment