-->
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 API vs. HQL
PostPosted: Thu May 17, 2007 5:48 am 
Senior
Senior

Joined: Sat Apr 21, 2007 11:01 pm
Posts: 144
What are peoples thoughts on Criteria API and HQL. Personaly i prefer HQL and find Criteria code horidly ugly. For example consider this beast:
Code:
   private Collection findSitesByAssetCriteria(AssetCriteria assetCriteria, Boolean includeArchivedSites) throws AdvancedSearchException {
       ArrayList siteIds = new ArrayList();
       //if no criteria set, return all sites
       if(
            (!assetCriteria.getAttribute().equals(""))
         || (!assetCriteria.getAttributeOperator().equals(""))
         || (!assetCriteria.getAttributeValue().equals(""))
         || (!assetCriteria.getAssetCondition().equals(""))
         || (!assetCriteria.getAssetRef().equals(""))
         || (!assetCriteria.getAssetType().equals(""))
         || (!assetCriteria.getManufacturer().equals(""))
         || (!assetCriteria.getModel().equals(""))
         || (!assetCriteria.getActivityGroup().equals(""))
         || (!assetCriteria.getActivitySearch().equals(""))
         || (!assetCriteria.getSelectedActivity().equals(""))
         || (assetCriteria.getActivityRequiredAfter() != null)
         || (assetCriteria.getActivityRequiredBefore() != null)
       ){
          //activities stuff
          Collection siteSurveyAssetsMatchingActivities = findMatchingActivities(assetCriteria);
          if (!(siteSurveyAssetsMatchingActivities.size() > 0)) {
             return new ArrayList();
          }
          //attribute stuff
          Collection matchingAssetAttributes = findMatchingAssetAttributes(assetCriteria);
          if (!(matchingAssetAttributes.size() > 0)) {
             return new ArrayList();
          }
          //matching library assets
          List listOfLibraryAssetsMatchingCriteria = findMatchingLibraryAssets(assetCriteria);
          if (!(listOfLibraryAssetsMatchingCriteria.size() > 0)) {
             return new ArrayList();
          }
          //asset condition related stuff
          Integer assetCondId = null;
          if (!assetCriteria.getAssetCondition().equals("")) {
             assetCondId = new Integer(assetCriteria.getAssetCondition());
          }
          Collection listOfAssetsMatchingCriteria = new ArrayList();
          String assetRef = assetCriteria.getAssetRef();
          Criteria assetHibernateCriteria = getSession().createCriteria(Asset.class);
          //find matching assets based on condition and ref
          if (((listOfLibraryAssetsMatchingCriteria!= null) && (listOfLibraryAssetsMatchingCriteria.size() > 0)) || (assetCondId != null) || !assetRef.equals("")) {
             if ((listOfLibraryAssetsMatchingCriteria != null) && (listOfLibraryAssetsMatchingCriteria.size() > 0)) {
                assetHibernateCriteria.add(Expression.in("libraryAsset", listOfLibraryAssetsMatchingCriteria));
             }
             if (assetCondId != null) {
                assetHibernateCriteria.add(Expression.eq("assetCondition.id", assetCondId));
             }
             if (!assetRef.equals("")) {
                assetHibernateCriteria.add(Expression.eq("ref", assetRef));
             }
             listOfAssetsMatchingCriteria = assetHibernateCriteria.list();
             if (!(listOfAssetsMatchingCriteria.size() > 0)) {
                return  new ArrayList();
             }
          }
          List listOfAssetsMatchingAttributes = new ArrayList();
          //any assets which match based on attribute match
          if (!assetCriteria.getAttribute().equals("") && !assetCriteria.getAttributeOperator().equals("") && !assetCriteria.getAttributeValue().equals("")) {
             if (matchingAssetAttributes != null) {
                for (Iterator iter = matchingAssetAttributes.iterator(); iter.hasNext(); ) {
                   AssetAttribute current = (AssetAttribute) iter.next();
                   listOfAssetsMatchingAttributes.add(current.getAsset());
                }
             }
          }
          else {//some assets do not appear in the list even if have entire list of AssetAttributes
             listOfAssetsMatchingAttributes = getSession().createCriteria(Asset.class).list();
          }
          Collection siteLocationIds = new ArrayList();
          Collection siteLocations = new ArrayList();
          Collection allMatchingAssets = new ArrayList();
          //remove dupes by putting into set
          allMatchingAssets = new HashSet(intersectionBetweenCollections(new HashSet(listOfAssetsMatchingAttributes), new HashSet(listOfAssetsMatchingCriteria)));
          if(
                (!assetCriteria.getAttribute().equals(""))
             || (!assetCriteria.getAttributeOperator().equals(""))
             || (!assetCriteria.getAttributeValue().equals(""))
             || (!assetCriteria.getAssetCondition().equals(""))
             || (!assetCriteria.getAssetRef().equals(""))
             || (!assetCriteria.getAssetType().equals(""))
             || (!assetCriteria.getManufacturer().equals(""))
             || (!assetCriteria.getModel().equals(""))
          ){
             for (Iterator iter = allMatchingAssets.iterator(); iter.hasNext(); ) {
                Asset currentAsset = (Asset) iter.next();
                siteLocationIds.add(currentAsset.getSiteLocation().getId());
             }
          }
          else {//some site locations do not appear in list even if have entire list of assets
             siteLocations = getSession().createCriteria(SiteLocation.class).list();
             for (Iterator iter = siteLocations.iterator(); iter.hasNext(); ) {
                SiteLocation current = (SiteLocation) iter.next();
                siteLocationIds.add(current.getId());
             }
          }
          Collection siteLocationIdsSet = new HashSet(siteLocationIds);
          Criteria siteLocationCriteria = getSession().createCriteria(SiteLocation.class);
          if (siteLocationIdsSet.size() > 0) {
             siteLocationCriteria.add(Expression.in("id", siteLocationIdsSet));
          }
       ///////////////////   
          Collection siteLocationIdsMatchingActivities = new ArrayList();
          if(
                (!assetCriteria.getActivityGroup().equals(""))
             || (!assetCriteria.getActivitySearch().equals(""))
             || (!assetCriteria.getSelectedActivity().equals(""))
             || (assetCriteria.getActivityRequiredAfter() != null)
             || (assetCriteria.getActivityRequiredBefore() != null)
          ){
             for (Iterator iter = siteSurveyAssetsMatchingActivities.iterator(); iter.hasNext(); ) {
                SiteSurveyAsset current = (SiteSurveyAsset) iter.next();
                siteLocationIdsMatchingActivities.add(current.getSiteLocation().getId());

             }
             //only restrict based on activities if there are any activity criteria
             Collection siteLocationIdsMatchingActivitiesSet = new HashSet(siteLocationIdsMatchingActivities);
             if ((siteSurveyAssetsMatchingActivities != null) && (siteSurveyAssetsMatchingActivities.size() > 0)) {
                siteLocationCriteria.add(Expression.in("id", siteLocationIdsMatchingActivitiesSet));
             }
          }
          //else {//some site locations do not appear in list even if have entire list of assets
          //   siteLocations = getSession().createCriteria(SiteLocation.class).list();
          //   for (Iterator iter = siteLocations.iterator(); iter.hasNext(); ) {
          //      SiteLocation current = (SiteLocation) iter.next();
          //      siteLocationIdsMatchingActivities.add(current.getId());
          //   }
          //}
          ////////////////////////
         List listOfMatchingSiteLocations = siteLocationCriteria.list();
         for (Iterator iter = listOfMatchingSiteLocations.iterator(); iter.hasNext(); ) {
            SiteLocation currentLocation = (SiteLocation) iter.next();
            siteIds.add(currentLocation.getSite().getSiteId());
         }
       }
       else {
         Collection listOfAllSites = getSession().createCriteria(Site.class).list();
         for (Iterator iter = listOfAllSites.iterator(); iter.hasNext(); ) {
            Site current = (Site) iter.next();
            siteIds.add(current.getSiteId());
         }
       }
       //match based on survey/surveyor
       Integer surveyId = null;
       if (!assetCriteria.getSurvey().equals("")) {
          surveyId = new Integer(assetCriteria.getSurvey());
       }
       Integer surveyorId = null;
       if (!assetCriteria.getSurveyor().equals("")) {
          surveyorId = new Integer(assetCriteria.getSurveyor());
       }
       ArrayList allSiteIds = new ArrayList();
       // Collection allSites = new ArrayList(); // The local variable allSites is never read???
       if ((surveyorId != null) || (surveyId != null)) {
          Collection matchingSiteIdsBasedOnSurveyCriteria = new ArrayList();
          matchingSiteIdsBasedOnSurveyCriteria = findMatchingSiteSurveys(surveyId, surveyorId);
          allSiteIds = intersectionBetweenCollections(siteIds, matchingSiteIdsBasedOnSurveyCriteria);
       }
       else {
          allSiteIds = siteIds;
       }
       Criteria siteCriteria = getSession().createCriteria(Site.class);
        if (!includeArchivedSites) {
           siteCriteria.add(Expression.eq("siteDeleted", Boolean.FALSE));
        }
       if ((allSiteIds != null) && (allSiteIds.size() > 0)) {
          Collection allMatches = new ArrayList();
          List currentList = new ArrayList();
          Collection currentSites = new ArrayList();
          //if all SiteIds > 2000, need to do search in batches or get hibernate error
          if (allSiteIds.size() > 2000) {
             int fromIndex = 0;
             int toIndex = 1000;
             for (int i = 0; i < allSiteIds.size(); i = i + 1000) {
                currentList = allSiteIds.subList(fromIndex, toIndex);
                   Criteria siteCriteriaSublist = getSession().createCriteria(Site.class);
                  if (!includeArchivedSites) {
                     siteCriteriaSublist.add(Expression.eq("siteDeleted", Boolean.FALSE));
                  }
                  siteCriteriaSublist.add(Expression.in("siteId", currentList));
                  currentSites = siteCriteriaSublist.list();
                allMatches.addAll(currentSites);
                fromIndex = toIndex;
                toIndex = toIndex + 1000;
                if (toIndex > allSiteIds.size()) {
                   toIndex = allSiteIds.size();
                }
                if (fromIndex == toIndex) {
                   break;
                }
             }
             return allMatches;
          }
          return siteCriteria.add(Expression.in("siteId", allSiteIds)).list();
       }
       return new ArrayList();
    }

This one singal function is used a lot on a complex search page which is horidly slow in PROD. Do you think we could acheive the same results with a dynamic HQL string?

Thoughts, comments and ranting appriciated!

_________________
Everytime you get an answer to your question without giving credit; god kills a kitten. :(


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 17, 2007 9:15 am 
Expert
Expert

Joined: Fri Aug 19, 2005 2:11 pm
Posts: 628
Location: Cincinnati
probably. they both turn into sql.

I'd guess the reason that is so slow is all the joining, list iteration, and list creation. Not the actual Criteria creation and parsing.

The thing is, the Criteria API was made for generating dynamic queries and is supposed to be a little easier to read than a bunch of string concatenations. It all depends on how it is written.

I definitely think that method is horribly written though

_________________
Chris

If you were at work doing this voluntarily, imagine what you'd want to see to answer a question.


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.