-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Criteria Query returns at most 10 results
PostPosted: Mon May 11, 2009 3:15 pm 
Newbie

Joined: Fri Sep 19, 2008 11:43 am
Posts: 3
I am using JPA + hibernate + Oracle:
- Hibernate: 3.2.6.ga
- Hibernate EntityManager: 3.3.2.GA
- Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit
- org.hibernate.dialect.Oracle10gDialect
- Oracle Driver 11.1.0.7.0

I am seeing some strange behavior when using JPA with Hibernate in combination with Oracle. When attempting to retrieve some results by criteria, I can only get back at most 10 results (when more than 10 qualify) no matter how high maxResults is set on the query. If maxResults is set to a number < 10, the correct number of results is returned.

I've seen a similar post about this from March of 2008 which seems to imply that this may be a problem with the distinct keyword. In my case, however, the distinct keyword is not even used.

If offset is set to be greater than 1 on the query, you will also get back the correct number of rows.
And, if I remove the column from the ORDER BY clause that enforces unique ordering on my query, I also get back the correct number of rows.

Stepping through hibernate's code, if I inspect the PreparedStatement on line 673 of the org.hibernate.loader.Loader, I can see that the jdbc fetch size is set to 10. I'm not sure if this is defaulted by oracle or hibernate, however, I would expect that multiple round trips would be made to the database to fetch all results matching the criteria, however, in my case, it appears that only one trip is being made to fetch the first 10 results matching the criteria. If I explicitly set the jdbc fetch size in my persistence.xml file to something higher (i.e. <property name="hibernate.jdbc.fetch_size" value="100"/>) I can get back at most the number I set the jdbc fetch size to.

Below is an example of my code that generates the query and gets the results:

Code:
Query query = em.createQuery("SELECT r FROM MyResult r WHERE r.attributes.person.id=:personIds ORDER BY r.attributes.resultDtTm.dtTm DESC, r.resultId DESC"); // removing r.resultId from the ORDER BY clause yields the correct number of results!
query.setMaxResults(11);
// Offset is 0 by default.
query.setParameter("personIds", "11111111-2222-3333-4444-555555555555")
List<MyResult> results = query.getResultList(); // Should return 11, but only returns 10!


The SQL generated by hibernate for this query is posted below. Copying and pasting this query into a oracle db viewer (such as sqldeveloper), substituting the '?' for the values passed above also yields the correct results.

Code:
select
        *
    from
        ( select
            result0_.result_id as result1_0_,
            result0_.comment_txt as comment5_0_,
            result0_.create_dt_tm as create8_0_,
            result0_.last_updt_dt_tm as last13_0_,
            result0_.owner_id as owner17_0_,
            result0_.owner_id_type as owner18_0_,
            result0_.person_id as person19_0_,
            result0_.person_id_type as person20_0_,
            result0_.result_dt_tm as result21_0_,
            result0_.result_text as result24_0_,
            result0_.result_type as result25_0_,
            result0_.version_create_id as version53_0_,
            result0_.version_create_id_type as version54_0_,
            result0_.result_vrsn as result55_0_
        from
            result result0_
        where
            result0_.person_id=?
        order by
            result0_.result_dt_tm DESC,
            result0_.result_id DESC )
    where
        rownum <= ?


Another workaround I have found is that overriding the Oracle10gDialect's getLimitString as such also appears to resolve the issue:

Code:
public class Oracle10gDialectMaxResultsWorkaround extends Oracle10gDialect
{   
    @Override
    public String getLimitString(String sql, boolean hasOffset)
    {
        StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
        pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
        pagingSelect.append(sql);
        if (hasOffset)
        {
            pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
        }
        else
        {
            pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > 0");
        }
        return pagingSelect.toString();
    }
}


This workaround was taken from: http://www.jroller.com/sjivan/entry/hibernate_and_oracle_pagination_gotcha
The workaround dialect from this post: https://forum.hibernate.org/viewtopic.php?f=1&t=984652 does not work for me.

It could also be noted that this query works fine in MySQL.

If anyone could shed some light on this strange behavior, I would really appreciate it. Thanks!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.