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!