Updated a couple of methods to be more in line with generic dao method pattern
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / taxon / TaxonDaoHibernateImpl.java
index 9eac2f416d3bdd75cbecce46488944a2977faf2c..077ae7a35999e5bac800e69641d09b9c890a4a79 100644 (file)
@@ -9,12 +9,17 @@
 package eu.etaxonomy.cdm.persistence.dao.hibernate.taxon;\r
 \r
 import java.lang.reflect.Field;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
+import java.util.Comparator;\r
 import java.util.HashSet;\r
 import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Set;\r
+import java.util.SortedSet;\r
+import java.util.TreeSet;\r
 import java.util.UUID;\r
 \r
 import org.apache.log4j.Logger;\r
@@ -76,6 +81,7 @@ import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
 import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
 import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
 \r
 \r
 /**\r
@@ -93,7 +99,6 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
        private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\r
                \r
        private String defaultField = "name.titleCache";\r
-       private String defaultSort = "name.titleCache_forSort";\r
        private Class<? extends TaxonBase> indexedClasses[]; \r
 \r
        public TaxonDaoHibernateImpl() {\r
@@ -114,23 +119,11 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
        public List<Taxon> getRootTaxa(ReferenceBase sec) {\r
                return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);\r
        }\r
-       \r
-       @Override\r
-       public TaxonBase findByUuid(UUID uuid) {\r
-               TaxonBase taxonBase = super.findByUuid(uuid);\r
-               if(taxonBase == null) \r
-                       return taxonBase;\r
-               \r
-               Hibernate.initialize(taxonBase.getName());\r
-               Hibernate.initialize(taxonBase.getSec());\r
-               return taxonBase; \r
-       }\r
-       \r
-       \r
+               \r
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
         */\r
-       public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {\r
+       public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications, List<String> propertyPaths) {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");\r
                if (onlyWithChildren == null){\r
                        onlyWithChildren = true;\r
@@ -166,21 +159,22 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                List<Taxon> results = new ArrayList<Taxon>();\r
                List<Taxon> taxa = crit.list();\r
                for(Taxon taxon : taxa){\r
+                       \r
+                       \r
                        //childTaxa\r
                        //TODO create restriction instead\r
-                       //Hibernate.initialize(taxon.getName());\r
-                       Hibernate.initialize(taxon.getSec());\r
-                       \r
                        // (a) not using cache fields\r
                        /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());\r
                        if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){\r
                                if (withMisapplications == true || ! taxon.isMisappliedName()){\r
+                                       defaultBeanInitializer.initialize(taxon, propertyPaths);\r
                                        results.add(taxon);\r
                                }\r
                        }*/\r
                        // (b) using cache fields\r
                        if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){\r
                                if (withMisapplications == true || ! taxon.isMisappliedName()){\r
+                                       defaultBeanInitializer.initialize(taxon, propertyPaths);\r
                                        results.add(taxon);\r
                                }\r
                        }\r
@@ -192,7 +186,7 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
         * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
         */\r
        public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {\r
-               return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications);\r
+               return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications, null);\r
        }\r
        \r
 \r
@@ -240,17 +234,13 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                criteria.setFetchMode( "name", FetchMode.JOIN );\r
                criteria.createAlias("name", "name");\r
                \r
+               String hqlQueryString = matchMode.queryStringFrom(queryString);\r
                if (matchMode == MatchMode.EXACT) {\r
-                       criteria.add(Restrictions.eq("name.nameCache", matchMode.queryStringFrom(queryString)));\r
+                       criteria.add(Restrictions.eq("name.nameCache", hqlQueryString));\r
                } else {\r
-                       criteria.add(Restrictions.ilike("name.nameCache", matchMode.queryStringFrom(queryString)));\r
+                       criteria.add(Restrictions.ilike("name.nameCache", hqlQueryString));\r
                }\r
-               \r
-\r
-//             if (queryString != null) {\r
-//                     criteria.add(Restrictions.ilike("name.nameCache", queryString));\r
-//             }\r
-//             \r
+                               \r
                if(pageSize != null) {\r
                        criteria.setMaxResults(pageSize);\r
                        if(pageNumber != null) {\r
@@ -261,6 +251,14 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                List<TaxonBase> results = criteria.list();\r
                return results;\r
        }\r
+       \r
+       public Integer countTaxaByName(String queryString, MatchMode matchMode, \r
+                       Boolean accepted) {\r
+               //TODO improve performance\r
+               List<TaxonBase> restultSet = getTaxaByName(queryString, matchMode, accepted, null, null);\r
+               return restultSet.size();\r
+       }\r
+       \r
 \r
        public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {\r
                return super.list(pagesize, page);\r
@@ -284,7 +282,29 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        return (List<RelationshipBase>)query.getResultList();\r
                }\r
        }\r
-\r
+       \r
+       /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */\r
+//     private boolean nullifyTaxonomicParent(Taxon taxon) {\r
+//\r
+//             try {\r
+//                     Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");\r
+//                     nullifyTaxonomicParent.invoke(taxon);\r
+//             } catch (NoSuchMethodException ex) {\r
+//                     logger.error("NoSuchMethod: " + ex.getMessage());\r
+//                     return false;\r
+//             } catch (IllegalArgumentException ex) {\r
+//                     logger.error("IllegalArgumentException: " + ex.getMessage());\r
+//                     return false;\r
+//             } catch (IllegalAccessException ex) {\r
+//                     logger.error("IllegalAccessException: " + ex.getMessage());\r
+//                     return false;\r
+//             } catch (InvocationTargetException ex) {\r
+//                     logger.error("IllegalAccessException: " + ex.getMessage());\r
+//                     return false;\r
+//             }\r
+//             return true;\r
+//     }\r
+       \r
        @Override\r
        public UUID delete(TaxonBase taxonBase) throws DataAccessException{\r
                if (taxonBase == null){\r
@@ -338,21 +358,37 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        Taxon taxon = (Taxon)taxonBase;\r
                                                \r
                        for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){\r
-                               TaxonRelationship relationToThisTaxon = iterator.next();\r
-                               iterator.remove();\r
-                               relationToThisTaxon.setFromTaxon(null);\r
-                               relationToThisTaxon.setToTaxon(null);\r
-                               getSession().delete(relationToThisTaxon);\r
-                       }\r
-                       \r
-                       for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){\r
                                TaxonRelationship relationFromThisTaxon = iterator.next();\r
                                iterator.remove();\r
+                               \r
+                               // decrease children count of taxonomic parent by one\r
+                               if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
+                                       Taxon toTaxon = relationFromThisTaxon.getToTaxon(); // parent\r
+                                       if (toTaxon != null) {\r
+                                               toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1);     \r
+                                       }\r
+                               }\r
                                relationFromThisTaxon.setToTaxon(null);\r
                                relationFromThisTaxon.setFromTaxon(null);\r
                                getSession().delete(relationFromThisTaxon);\r
                        }\r
                        \r
+                       for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){\r
+                               TaxonRelationship relationToThisTaxon = iterator.next();\r
+                               iterator.remove();\r
+                               \r
+                // set parent cache of child to null\r
+                               if (relationToThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
+                                       Taxon fromTaxon = relationToThisTaxon.getFromTaxon(); // child\r
+                                       if (fromTaxon != null) {\r
+                                               fromTaxon.nullifyTaxonomicParent();\r
+                                       }\r
+                               }\r
+                               relationToThisTaxon.setFromTaxon(null);\r
+                               relationToThisTaxon.setToTaxon(null);\r
+                               getSession().delete(relationToThisTaxon);\r
+                       }\r
+                       \r
                        //SynonymRelationships\r
                        for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){\r
                                SynonymRelationship synonymRelation = iterator.next();\r
@@ -379,6 +415,8 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                                getSession().delete(taxonDescription);\r
                        }\r
                        \r
+                       taxon.nullifyTaxonomicParent();\r
+\r
                } else { //is Synonym\r
                        Synonym synonym = (Synonym)taxonBase;\r
                        for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){\r
@@ -480,9 +518,9 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                }\r
        }\r
 \r
-       public int countTaxa(String queryString, Boolean accepted) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.countTaxa(String queryString, Boolean accepted)");\r
-        QueryParser queryParser = new QueryParser("name.titleCache", new SimpleAnalyzer());\r
+       public int count(Class<? extends TaxonBase> clazz, String queryString) {\r
+               checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString, Boolean accepted)");\r
+        QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
                \r
                try {\r
                        org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
@@ -490,14 +528,10 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());\r
                        org.hibernate.search.FullTextQuery fullTextQuery = null;\r
                        \r
-                       if(accepted == null) {\r
-                               fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);\r
+                       if(clazz == null) {\r
+                               fullTextQuery = fullTextSession.createFullTextQuery(query, type);\r
                        } else {\r
-                               if(accepted) {\r
-                                       fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);\r
-                               } else {\r
-                                       fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);\r
-                               }\r
+                               fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);\r
                        }\r
                        \r
                    Integer  result = fullTextQuery.getResultSize();\r
@@ -535,18 +569,14 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                return (Integer)criteria.uniqueResult();\r
        }\r
 \r
-       public int countTaxaByName(Boolean accepted, String genusOrUninomial,   String infraGenericEpithet, String specificEpithet,     String infraSpecificEpithet, Rank rank) {\r
+       public int countTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial,   String infraGenericEpithet, String specificEpithet,     String infraSpecificEpithet, Rank rank) {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial,   String infraGenericEpithet, String specificEpithet,     String infraSpecificEpithet, Rank rank)");\r
         Criteria criteria = null;\r
                \r
-               if(accepted == null) {\r
+               if(clazz == null) {\r
                        criteria = getSession().createCriteria(TaxonBase.class);\r
                } else {\r
-                       if(accepted) {\r
-                               criteria = getSession().createCriteria(Taxon.class);\r
-                       } else {\r
-                               criteria = getSession().createCriteria(Synonym.class);\r
-                       }\r
+                       criteria = getSession().createCriteria(clazz);          \r
                }\r
                \r
                criteria.setFetchMode( "name", FetchMode.JOIN );\r
@@ -577,38 +607,41 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                return (Integer)criteria.uniqueResult();\r
        }\r
 \r
-       public List<TaxonBase> findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,  Integer pageNumber) {\r
+       public List<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,  Integer pageNumber) {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,      Integer pageNumber)");\r
                Criteria criteria = null;\r
                \r
-               if(accepted == null) {\r
+               if(clazz == null) {\r
                        criteria = getSession().createCriteria(TaxonBase.class);\r
                } else {\r
-                       if(accepted) {\r
-                               criteria = getSession().createCriteria(Taxon.class);\r
-                       } else {\r
-                               criteria = getSession().createCriteria(Synonym.class);\r
-                       }\r
+                       criteria = getSession().createCriteria(clazz);\r
                }\r
                \r
                criteria.setFetchMode( "name", FetchMode.JOIN );\r
                criteria.createAlias("name", "name");\r
                \r
-               if(genusOrUninomial != null) {\r
+               if(genusOrUninomial == null) {\r
+                       criteria.add(Restrictions.isNull("name.genusOrUninomial"));\r
+               } else if(!genusOrUninomial.equals("*")) {\r
                        criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));\r
                }\r
                \r
-               if(infraGenericEpithet != null) {\r
-                       criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
-               } else {\r
+               if(infraGenericEpithet == null) {\r
                        criteria.add(Restrictions.isNull("name.infraGenericEpithet"));\r
-               }\r
+               } else if(!infraGenericEpithet.equals("*")) {\r
+                       criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
+               } \r
                \r
-               if(specificEpithet != null) {\r
+               if(specificEpithet == null) {\r
+                       criteria.add(Restrictions.isNull("name.specificEpithet"));\r
+               } else if(!specificEpithet.equals("*")) {\r
                        criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));\r
+                       \r
                }\r
                \r
-               if(infraSpecificEpithet != null) {\r
+               if(infraSpecificEpithet == null) {\r
+                       criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));\r
+               } else if(!infraSpecificEpithet.equals("*")) {\r
                        criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));\r
                }\r
                \r
@@ -628,30 +661,31 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                return (List<TaxonBase>)criteria.list();\r
        }\r
 \r
-       public List<TaxonRelationship> getRelatedTaxa(Taxon taxon,      TaxonRelationshipType type, Integer pageSize, Integer pageNumber) {\r
+       public List<TaxonRelationship> getRelatedTaxa(Taxon taxon,      TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-            Query query = null;\r
+                       Criteria criteria = getSession().createCriteria(TaxonRelationship.class);\r
             \r
-                   if(type == null) {\r
-                           query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo");\r
-                   } else {\r
-                           query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");\r
-                           query.setParameter("type",type);\r
-                   }\r
+                       criteria.add(Restrictions.eq("relatedTo", taxon));\r
+                   if(type != null) {\r
+                       criteria.add(Restrictions.eq("type", type));\r
+                   } \r
                \r
-                   query.setParameter("relatedTo", taxon);\r
+            addOrder(criteria,orderHints);\r
                \r
                    if(pageSize != null) {\r
-                       query.setMaxResults(pageSize);\r
+                       criteria.setMaxResults(pageSize);\r
                        if(pageNumber != null) {\r
-                           query.setFirstResult(pageNumber * pageSize);\r
+                               criteria.setFirstResult(pageNumber * pageSize);\r
                        } else {\r
-                           query.setFirstResult(0);\r
+                               criteria.setFirstResult(0);\r
                        }\r
                    }\r
                \r
-                   return (List<TaxonRelationship>)query.list();\r
+                   List<TaxonRelationship> result = (List<TaxonRelationship>)criteria.list();\r
+                   defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+                   \r
+                   return result;\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
                        query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
@@ -670,38 +704,54 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                    }\r
                        \r
                        List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();\r
-                       for(TaxonRelationship relationship : result) {\r
-                               Hibernate.initialize(relationship.getFromTaxon());\r
+                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+                       \r
+                       // Ugly, but for now, there is no way to sort on a related entity property in Envers,\r
+                       // and we can't live without this functionality in CATE as it screws up the whole \r
+                       // taxon tree thing\r
+                       if(orderHints != null && !orderHints.isEmpty()) {\r
+                           SortedSet<TaxonRelationship> sortedList = new TreeSet<TaxonRelationship>(new TaxonRelationshipFromTaxonComparator());\r
+                           sortedList.addAll(result);\r
+                           return new ArrayList<TaxonRelationship>(sortedList);\r
                        }\r
                        \r
                        return result;\r
                }\r
        }\r
+       \r
+       class TaxonRelationshipFromTaxonComparator implements Comparator<TaxonRelationship> {\r
 \r
-       public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber) {\r
+               public int compare(TaxonRelationship o1, TaxonRelationship o2) {\r
+                       return o1.getFromTaxon().getTitleCache().compareTo(o2.getFromTaxon().getTitleCache());\r
+               }\r
+               \r
+       }\r
+\r
+       public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Query query = null;\r
-\r
-                       if(type == null) {\r
-                               query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo");\r
-                       } else {\r
-                               query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");\r
-                               query.setParameter("type",type);\r
-                       }\r
-\r
-                       query.setParameter("relatedTo", taxon);\r
-\r
-                       if(pageSize != null) {\r
-                               query.setMaxResults(pageSize);\r
-                               if(pageNumber != null) {\r
-                                       query.setFirstResult(pageNumber * pageSize);\r
-                               } else {\r
-                                       query.setFirstResult(0);\r
-                               }\r
-                       }\r
-\r
-                       return (List<SynonymRelationship>)query.list();\r
+            Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
+            \r
+                       criteria.add(Restrictions.eq("relatedTo", taxon));\r
+                   if(type != null) {\r
+                       criteria.add(Restrictions.eq("type", type));\r
+                   } \r
+               \r
+            addOrder(criteria,orderHints);\r
+               \r
+                   if(pageSize != null) {\r
+                       criteria.setMaxResults(pageSize);\r
+                       if(pageNumber != null) {\r
+                               criteria.setFirstResult(pageNumber * pageSize);\r
+                       } else {\r
+                               criteria.setFirstResult(0);\r
+                       }\r
+                   }\r
+               \r
+                   List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();\r
+                   defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+                   \r
+                   return result;\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());\r
                        query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
@@ -720,15 +770,13 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                    }\r
                        \r
                        List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
-                       for(SynonymRelationship relationship : result) {\r
-                               Hibernate.initialize(relationship.getSynonym());\r
-                       }\r
+                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
                        \r
                        return result;\r
                }\r
        }\r
 \r
-       public List<TaxonBase> searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber) {\r
+       public List<TaxonBase> search(Class<? extends TaxonBase> clazz, String queryString,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)  {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted,     Integer pageSize, Integer pageNumber)");\r
                QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
                List<TaxonBase> results = new ArrayList<TaxonBase>();\r
@@ -739,18 +787,13 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
                        org.hibernate.search.FullTextQuery fullTextQuery = null;\r
                        \r
-                       if(accepted == null) {\r
+                       if(clazz == null) {\r
                                fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);\r
                        } else {\r
-                               if(accepted) {\r
-                                       fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);\r
-                               } else {\r
-                                       fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);\r
-                               }\r
+                               fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);\r
                        }\r
                        \r
-                       org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));\r
-                       fullTextQuery.setSort(sort);\r
+                       addOrder(fullTextQuery,orderHints);\r
                        \r
                    if(pageSize != null) {\r
                        fullTextQuery.setMaxResults(pageSize);\r
@@ -762,9 +805,7 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        }\r
                    \r
                    List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();\r
-                   for(TaxonBase taxonBase : result) {\r
-                       Hibernate.initialize(taxonBase.getName());\r
-                   }\r
+                   defaultBeanInitializer.initializeAll(result, propertyPaths);\r
                    return result;\r
 \r
                } catch (ParseException e) {\r
@@ -818,56 +859,4 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                }\r
                return alternativeQueryString;\r
        }\r
-\r
-       public int count(String queryString) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString)");\r
-        QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
-               \r
-               try {\r
-                       org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
-               \r
-                       FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());\r
-                       org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);\r
-                               \r
-                   return fullTextQuery.getResultSize();\r
-\r
-               } catch (ParseException e) {\r
-                       throw new QueryParseException(e, queryString);\r
-               }\r
-       }\r
-\r
-       public List<TaxonBase> search(String queryString, Integer pageSize,     Integer pageNumber) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.search(String queryString, Integer pageSize, Integer pageNumber)");\r
-               QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
-               List<TaxonBase> results = new ArrayList<TaxonBase>();\r
-                \r
-               try {\r
-                       org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
-                       \r
-                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
-                       \r
-                       org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);\r
-                       \r
-                       org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));\r
-                       fullTextQuery.setSort(sort);\r
-                   \r
-                   if(pageSize != null) {\r
-                       fullTextQuery.setMaxResults(pageSize);\r
-                           if(pageNumber != null) {\r
-                               fullTextQuery.setFirstResult(pageNumber * pageSize);\r
-                           } else {\r
-                               fullTextQuery.setFirstResult(0);\r
-                           }\r
-                       }\r
-                   \r
-                   List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();\r
-                   for(TaxonBase taxonBase : result) {\r
-                       Hibernate.initialize(taxonBase.getName());\r
-                   }\r
-                   return result;\r
-\r
-               } catch (ParseException e) {\r
-                       throw new QueryParseException(e, queryString);\r
-               }\r
-       }\r
 }\r