-->
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: Global COUNT method in DAO
PostPosted: Fri Aug 29, 2008 12:06 pm 
Newbie

Joined: Fri Aug 29, 2008 9:07 am
Posts: 16
Location: edinburgh/zielona gora
version : 3.2.6ga
DB: Mysql 5.1
Java beginner

Hi all, first of all I would like to ask quite general question.

What do you think about having a method like 'countNamedQueryResults' in DAO class.

The method will consume namedQuery name and a HashMap of properties for initialization of named parameters (key ->namedparametername, value-> value to be used for that parameter).

The method will transform namedquery and return only number od records which would be returned by that query with given parameters.

The purpose of this is to stop writing separate counting queries corresponding to results's getters queries.

I know I could use list().size() but that would force hibernate to select all objects and then count them (correct me if I am wrong).

Here is my initial proposition, with many bugs ect. but should work for named queries formatted like :
SELECT Entity FROM entities and joins and whatever else s WHERE parametrisedconditions1 = :val1 and parametrisedconditions2 = :val2 ...

What do you think about this ?



Code:
public Number count(String  namedquery, HashMap paramsmap ){
       
             Session session = null;
       Transaction tx = null;
       Object identity = null;
       Number cnt = null;
       
        try {
           
              identity = createSession();
              session = currentSession();
              tx = session.beginTransaction();
             
           
                String queryString  =  session.getNamedQuery(namedquery).getQueryString();
               
                // add count statement to given namged query
                // to do: check this reg expression if fair enought
                queryString = queryString.replaceAll("SELECT\\s+(\\w+)\\s+FROM",   "SELECT COUNT($1.id) FROM ");
               
                Query q = session.createQuery(queryString)  ;
              String namedParams [] = session.getNamedQuery(namedquery) .getNamedParameters();

//q.setProperties(paramsmap)     ;

                for (String namedparam :  namedParams){
                       q.setParameter(namedparam, paramsmap.get(namedparam) ,Hibernate.INTEGER ) ;
                }

            cnt = (Number) q.uniqueResult();
             
            tx.commit();
            tx=null;           
            return cnt ;
           
        } catch (Exception e) {
            log.error(e);
            tx.rollback();
        } finally {
           
            closeSession(identity);
        }
       
        return null ;
    }


example named query:
Code:
@NamedQuery(name = "StrukturyCment.getChildsByParentId", query = "SELECT s FROM structs  s WHERE s.deleted = 0 and s.parent=:parent"),


btw: hibernate bug?
when I use query.setProperties(paramsmap) hibernate requires different types for named parameters than fx. query.setInteger('param',val), example:
I can easly do something like that:

query.SetInteger('parent', new Integer(123123) );

but when I do something like this:
HashMap paramsmappng = new HashMap();
paramsmappng.put("parent", new Integer( 293398 )) ;

query.setProperties( paramsmappng ) ;

I get error like:
instance not of expected entity type: java.lang.Integer is not a: my.package.myClass

I would like to ommit Hibernate.INTEGER as well - paramsmap should be able to store different types of values

ufff - hope anyone will at last try to understand at last part of my scribbles. If you dont please ask question :)

cheers for any ...
[/code]


Top
 Profile  
 
 Post subject: Re: Global COUNT method in DAO
PostPosted: Fri Aug 29, 2008 1:38 pm 
Newbie

Joined: Thu Aug 28, 2008 3:31 am
Posts: 5
Quote:
I get error like:
instance not of expected entity type: java.lang.Integer is not a: my.package.myClass

I think if you show your real error info should be more helpful to position your issue.

Here, I find this error info ,
Code:
instance not of expected entity type:
, is printed by
Code:
org.hibernate.persister.entity.AbstractEntityPersister.getSubclassEntityPersister(Object, SessionFactoryImplementor, EntityMode)
. And this function is invoked by
Code:
org.hibernate.loader.Loader.doQuery(SessionImplementor, QueryParameters, boolean)
. The following is the full copy of the doQuery function:

Code:
private List doQuery(
         final SessionImplementor session,
         final QueryParameters queryParameters,
         final boolean returnProxies) throws SQLException, HibernateException {

      final RowSelection selection = queryParameters.getRowSelection();
      final int maxRows = hasMaxRows( selection ) ?
            selection.getMaxRows().intValue() :
            Integer.MAX_VALUE;

      final int entitySpan = getEntityPersisters().length;

      final ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan * 10 );
      final PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
      [color=red]final ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), selection, session );[/color]
// would be great to move all this below here into another method that could also be used
// from the new scrolling stuff.
//
// Would need to change the way the max-row stuff is handled (i.e. behind an interface) so
// that I could do the control breaking at the means to know when to stop
      final LockMode[] lockModeArray = getLockModes( queryParameters.getLockModes() );
      [color=green]final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session );[/color]
      final boolean createSubselects = isSubselectLoadingEnabled();
      final List subselectResultKeys = createSubselects ? new ArrayList() : null;
      final List results = new ArrayList();

      try {

         handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session );

         EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row

         if ( log.isTraceEnabled() ) log.trace( "processing result set" );

         int count;
         for ( count = 0; count < maxRows && rs.next(); count++ ) {
            
            if ( log.isTraceEnabled() ) log.debug("result set row: " + count);

            Object result = getRowFromResultSet(
                  rs,
                  session,
                  queryParameters,
                  lockModeArray,
                  optionalObjectKey,
                  hydratedObjects,
                  keys,
                  returnProxies
            );
            results.add( result );

            if ( createSubselects ) {
               subselectResultKeys.add(keys);
               keys = new EntityKey[entitySpan]; //can't reuse in this case
            }
            
         }

         if ( log.isTraceEnabled() ) {
            log.trace( "done processing result set (" + count + " rows)" );
         }

      }
      finally {
         session.getBatcher().closeQueryStatement( st, rs );
      }

      initializeEntitiesAndCollections( hydratedObjects, rs, session, queryParameters.isReadOnly() );

      if ( createSubselects ) createSubselects( subselectResultKeys, queryParameters, session );

      return results; //getResultList(results);

   }


Do you notice the order of the red color code and the green one?
Actually, the query has been done before the exception with your error info. The error should be ocurred while Hibernate construct some corresponding entities with the resultset. So, I think you should check your application again.

Hope this is helpful.


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.