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

Popular posts from this blog

sql - dynamically varied number of conditions in the 'where' statement using LINQ -

asp.net mvc - Dynamically Generated Ajax.BeginForm -

Debug on symbian -