-->
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.  [ 2 posts ] 
Author Message
 Post subject: Criteria and the count() issue
PostPosted: Wed Sep 15, 2004 4:12 am 
Newbie

Joined: Mon Aug 30, 2004 9:54 am
Posts: 8
Adding support for SQL count() to the Criteria API has been discussed here before, so I try to avoid that issue. But in order to work around this problem I encountered a new one.

Problem description
I use the Criteria API to dynamically construct filters and ordering, which works as expected. However, paging of result sets is encapsulated in a data handling class which takes a given Criteria instance, adds paging and sorting as needed and stores the results. Tables sizes are huge sometimes, so counting the result set in memory is not an option.

Current workaround concept
Code:
Session s = Persistance.getSession();
StringBuffer sql = new StringBuffer("select count(*) from ");
sql.append(criteria.getCriteriaClass().getName());

// here we should append the 'where'-clause to sql
// but: How can we get it from a given Criteria instance?

int recordCount = ((Integer) s.iterate(sql.toString()).next()).intValue();


Doesn anybody know how to create the SQL 'where ...' fragment from a Criteria instance? That would help me a lot. Thanks in advance,

Christian


Top
 Profile  
 
 Post subject: Criteria expert needed
PostPosted: Fri Sep 17, 2004 6:44 am 
Newbie

Joined: Mon Aug 30, 2004 9:54 am
Posts: 8
I've been working on the issue described above, and this is what I've got until now:
Code:
try {
    Session s = Persistance.getSession();
   
    StringBuffer sql = new StringBuffer("select count(*) from ");
    sql.append(criteria.getCriteriaClass().getName());

    CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;
    Iterator iter = criteriaImpl.iterateExpressionEntries();
    if (iter.hasNext()) {
        StringBuffer condition = new StringBuffer(30);
       
        while ( iter.hasNext() ) {
            CriteriaImpl.CriterionEntry ee = (CriteriaImpl.CriterionEntry) iter.next();
            String sqlString = ee.getCriterion().toSqlString(
                (SessionFactoryImplementor)s.getSessionFactory(),
                criteriaImpl.getPersistentClass( ee.getAlias() ),
                ee.getAlias(),
                criteriaImpl.getAliasClasses()
            );
            condition.append(sqlString);
            if ( iter.hasNext() ) condition.append(" and ");
        }
       
        sql.append(" where ").append(condition);
    }
    _log.debug("Record count query: " + sql.toString());
    recordCount = ((Integer) s.iterate(sql.toString()).next())
            .intValue();
    pageCount = (recordCount / PAGE_SIZE) - 1;
} catch (HibernateException e) {
    _log.error("Couldn't calculate record count", e);
    recordCount = -1;
    pageCount = 1;
}


It works for queries not containing parameters, but will fail because of unresolved parameters otherwise:

Code:
31000 [http-80-Processor24] DEBUG com.pi.portal.data.BasicWrapper  - Record count query: select count(*) from com.pi.tcomadm.entities.Stadt where lower(this.name) like ?
Hibernate: select count(*) as x0_0_ from stadt stadt0_ where (lower(this.name)like ? )
31000 [http-80-Processor24] WARN  net.sf.hibernate.util.JDBCExceptionReporter  - SQL Error: 0, SQLState: 07001
31000 [http-80-Processor24] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - No value specified for parameter 1
31000 [http-80-Processor24] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - Could not execute query
java.sql.SQLException: No value specified for parameter 1
   at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2264)
   at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2217)
   at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1511)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:92)
   at net.sf.hibernate.impl.BatcherImpl.getResultSet(BatcherImpl.java:87)
   at net.sf.hibernate.loader.Loader.getResultSet(Loader.java:875)
   at net.sf.hibernate.hql.QueryTranslator.iterate(QueryTranslator.java:868)
   at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1610)
   at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1583)
   at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1575)
   at com.pi.portal.data.BasicWrapper.<init>(BasicWrapper.java:86)

...


Obviously I'd need to attach the named values somehow. Maybe session.iterate() isn't the method of choice here, too, because AFAIK it doesn't support parameters.

How could I get that map of parameter values from the criteria? Any help is greatly appreciated. Best regards,

- Christian


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

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.