method name harmonization
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / name / TaxonNameDaoHibernateImpl.java
index 0bcc81ea5f7c7eb318d0d45d73cefb5d1a222af8..255a2b570aec3b1e3e0bffd1849773e064833d42 100644 (file)
@@ -9,34 +9,52 @@
  */\r
 package eu.etaxonomy.cdm.persistence.dao.hibernate.name;\r
 \r
+import java.util.ArrayList;\r
 import java.util.List;\r
+import java.util.Set;\r
+import java.util.UUID;\r
 \r
 import org.apache.log4j.Logger;\r
 import org.hibernate.Criteria;\r
 import org.hibernate.Query;\r
+import org.hibernate.Session;\r
 import org.hibernate.criterion.Criterion;\r
 import org.hibernate.criterion.Order;\r
 import org.hibernate.criterion.Projections;\r
 import org.hibernate.criterion.Restrictions;\r
 import org.hibernate.envers.query.AuditEntity;\r
 import org.hibernate.envers.query.AuditQuery;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.beans.factory.annotation.Qualifier;\r
 import org.springframework.stereotype.Repository;\r
 \r
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.common.RelationshipBase;\r
+import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;\r
+import eu.etaxonomy.cdm.model.name.BacterialName;\r
 import eu.etaxonomy.cdm.model.name.BotanicalName;\r
+import eu.etaxonomy.cdm.model.name.CultivarPlantName;\r
 import eu.etaxonomy.cdm.model.name.HybridRelationship;\r
 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;\r
 import eu.etaxonomy.cdm.model.name.NameRelationship;\r
 import eu.etaxonomy.cdm.model.name.NameRelationshipType;\r
 import eu.etaxonomy.cdm.model.name.NonViralName;\r
 import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;\r
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;\r
-import eu.etaxonomy.cdm.model.name.TypeDesignationStatus;\r
+import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;\r
+import eu.etaxonomy.cdm.model.name.ViralName;\r
+import eu.etaxonomy.cdm.model.name.ZoologicalName;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.cdm.model.view.AuditEvent;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;\r
 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
 import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
 \r
 /**\r
  * @author a.mueller\r
@@ -50,11 +68,21 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
        @SuppressWarnings("unused")\r
        private static final Logger logger = Logger.getLogger(TaxonNameDaoHibernateImpl.class);\r
 \r
+       @Autowired\r
+       private ITaxonDao taxonDao;\r
+\r
        public TaxonNameDaoHibernateImpl() {\r
                super(TaxonNameBase.class); \r
+               indexedClasses = new Class[6];\r
+               indexedClasses[0] = BacterialName.class;\r
+               indexedClasses[1] = BotanicalName.class;\r
+               indexedClasses[2] = CultivarPlantName.class;\r
+               indexedClasses[3] = NonViralName.class;\r
+               indexedClasses[4] = ViralName.class;\r
+               indexedClasses[5] = ZoologicalName.class;\r
        }\r
 \r
-       public int countHybridNames(BotanicalName name, HybridRelationshipType type) {\r
+       public int countHybridNames(NonViralName name, HybridRelationshipType type) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
                        Query query = null;\r
@@ -91,6 +119,24 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                return (Integer)criteria.uniqueResult();\r
        }\r
 \r
+       public int countNames(String queryString, MatchMode matchMode, List<Criterion> criteria) {\r
+               \r
+               Criteria crit = getSession().createCriteria(type);\r
+               if (matchMode == MatchMode.EXACT) {\r
+                       crit.add(Restrictions.eq("nameCache", matchMode.queryStringFrom(queryString)));\r
+               } else {\r
+                       crit.add(Restrictions.ilike("nameCache", matchMode.queryStringFrom(queryString)));\r
+               }\r
+               if(criteria != null) {\r
+                       for (Criterion criterion : criteria) {\r
+                               crit.add(criterion);\r
+                       }\r
+               }\r
+\r
+               crit.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
+               return (Integer)crit.uniqueResult();\r
+       }\r
+       \r
        public int countNames(String genusOrUninomial, String infraGenericEpithet,      String specificEpithet, String infraSpecificEpithet, Rank rank) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
@@ -166,21 +212,22 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                }\r
        }\r
 \r
-       public int countRelatedNames(TaxonNameBase name, NameRelationshipType type) {\r
+       public int countNameRelationships(TaxonNameBase name, NameRelationship.Direction direction, NameRelationshipType type) {\r
+               \r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
                        Query query = null;\r
                        if(type == null) {\r
-                               query = getSession().createQuery("select count(relation) from NameRelationship relation where relation.relatedFrom = :name");\r
+                               query = getSession().createQuery("select count(relation) from NameRelationship relation where relation." + direction +" = :name");\r
                        } else {\r
-                               query = getSession().createQuery("select count(relation) from NameRelationship relation where relation.relatedFrom = :name and relation.type = :type");\r
+                               query = getSession().createQuery("select count(relation) from NameRelationship relation where relation." + direction +" = :name and relation.type = :type");\r
                                query.setParameter("type", type);\r
                        }\r
                        query.setParameter("name",name);\r
                        return ((Long)query.uniqueResult()).intValue();\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));\r
+                       query.add(AuditEntity.relatedId(direction.toString()).eq(name.getId()));\r
                        query.addProjection(AuditEntity.id().count("id"));\r
 \r
                        if(type != null) {\r
@@ -191,52 +238,42 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                }\r
        }\r
 \r
-       public int countTypeDesignations(TaxonNameBase name, TypeDesignationStatus status) {\r
-               AuditEvent auditEvent = getAuditEventFromContext();\r
-               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Query query = null;\r
-                       if(status == null) {\r
-                               query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name");\r
-                       } else {\r
-                               query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name and designation.typeStatus = :status");\r
-                               query.setParameter("status", status);\r
-                       }\r
-                       query.setParameter("name",name);\r
-                       return ((Long)query.uniqueResult()).intValue();\r
+       public int countTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status) {\r
+               checkNotInPriorView("countTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status)");\r
+               Query query = null;\r
+               if(status == null) {\r
+                       query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name");\r
                } else {\r
-                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TypeDesignationBase.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId("typifiedNames").eq(name.getId()));\r
-                       query.addProjection(AuditEntity.id().count("id"));\r
-\r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("typeStatus").eq(status.getId()));\r
-                       }\r
-\r
-                       return ((Long)query.getSingleResult()).intValue();\r
+                       query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name and designation.typeStatus = :status");\r
+                       query.setParameter("status", status);\r
                }\r
+               query.setParameter("name",name);\r
+               return ((Long)query.uniqueResult()).intValue();\r
        }\r
 \r
-       public List<HybridRelationship> getHybridNames(BotanicalName name, HybridRelationshipType type, Integer pageSize, Integer pageNumber) {\r
+       public List<HybridRelationship> getHybridNames(NonViralName name, HybridRelationshipType 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
-                       if(type == null) {\r
-                               query = getSession().createQuery("select relation from HybridRelationship relation where relation.relatedFrom = :name");\r
-                       } else {\r
-                               query = getSession().createQuery("select relation from HybridRelationship relation where relation.relatedFrom = :name and relation.type = :type");\r
-                               query.setParameter("type", type);\r
+                       Criteria criteria = getSession().createCriteria(HybridRelationship.class);\r
+                       criteria.add(Restrictions.eq("relatedFrom", name));\r
+                       if(type != null) {\r
+                               criteria.add(Restrictions.eq("type", type));\r
                        }\r
-                       query.setParameter("name",name);\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
-                       return (List<HybridRelationship>)query.list();\r
+                       \r
+                       addOrder(criteria, orderHints);\r
+                       \r
+                       List<HybridRelationship> results = (List<HybridRelationship>)criteria.list();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(HybridRelationship.class,auditEvent.getRevisionNumber());\r
                        query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));\r
@@ -254,34 +291,45 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                                }\r
                        }\r
 \r
-                       return (List<HybridRelationship>)query.getResultList();\r
+                       List<HybridRelationship> results =  (List<HybridRelationship>)query.getResultList();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
                }\r
        }\r
 \r
-       public List<NameRelationship> getRelatedNames(TaxonNameBase name, NameRelationshipType type, Integer pageSize, Integer pageNumber) {\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao#getNameRelationships(eu.etaxonomy.cdm.model.name.TaxonNameBase, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction, eu.etaxonomy.cdm.model.name.NameRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+        */\r
+       public List<NameRelationship> getNameRelationships(TaxonNameBase name, NameRelationship.Direction direction, \r
+                       NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, \r
+                       List<String> propertyPaths) {\r
+               \r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Query query = null;\r
-                       if(type == null) {\r
-                               query = getSession().createQuery("select relation from NameRelationship relation where relation.relatedFrom = :name");\r
-                       } else {\r
-                               query = getSession().createQuery("select relation from NameRelationship relation where relation.relatedFrom = :name and relation.type = :type");\r
-                               query.setParameter("type", type);\r
+                       Criteria criteria = getSession().createCriteria(NameRelationship.class);\r
+                       if (name != null || direction != null){\r
+                               criteria.add(Restrictions.eq(direction.toString(), name));\r
+                       }\r
+                       if(type != null) {\r
+                               criteria.add(Restrictions.eq("type", type));\r
                        }\r
-                       query.setParameter("name",name);\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
-                       return (List<NameRelationship>)query.list();\r
+                       addOrder(criteria, orderHints);\r
+                       \r
+                       List<NameRelationship> results = (List<NameRelationship>)criteria.list();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));\r
+                       query.add(AuditEntity.relatedId(direction.toString()).eq(name.getId()));\r
 \r
                        if(type != null) {\r
                                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
@@ -296,50 +344,51 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                                }\r
                        }\r
 \r
-                       return (List<NameRelationship>)query.getResultList();\r
+                       List<NameRelationship> results = (List<NameRelationship>)query.getResultList();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
                }\r
        }\r
+       \r
+       public List<TypeDesignationBase> getTypeDesignations(TaxonNameBase name, TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,        List<String> propertyPaths){\r
+               return getTypeDesignations(name, null, status, pageSize, pageNumber, propertyPaths);\r
+       }\r
+       \r
+       public <T extends TypeDesignationBase> List<T> getTypeDesignations(TaxonNameBase name, \r
+                               Class<T> type,\r
+                               TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,\r
+                               List<String> propertyPaths){\r
+               checkNotInPriorView("getTypeDesignations(TaxonNameBase name,TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,     List<String> propertyPaths)");\r
+               Query query = null;\r
+               String queryString = "select designation from TypeDesignationBase designation join designation.typifiedNames name where name = :name";\r
+\r
+               if(status != null) {\r
+                       queryString +=  " and designation.typeStatus = :status";\r
+               }\r
+               if(type != null){\r
+                       queryString +=  " and designation.class = :type";\r
+               }\r
 \r
-       public List<TypeDesignationBase> getTypeDesignations(TaxonNameBase name, TypeDesignationStatus status, Integer pageSize, Integer pageNumber) {\r
-               AuditEvent auditEvent = getAuditEventFromContext();\r
-               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Query query = null;\r
-                       if(status == null) {\r
-                               query = getSession().createQuery("select designation from TypeDesignationBase designation join designation.typifiedNames name where name = :name");\r
-                       } else {\r
-                               query = getSession().createQuery("select designation from TypeDesignationBase designation join designation.typifiedNames name where name = :name and designation.typeStatus = :status");\r
-                               query.setParameter("status", status);\r
-                       }\r
-                       query.setParameter("name",name);\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
-                       return (List<TypeDesignationBase>)query.list();\r
-               } else {\r
-                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TypeDesignationBase.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId("typifiedNames").eq(name.getId()));\r
+               query = getSession().createQuery(queryString);\r
+               \r
+               if(status != null) {            \r
+                       query.setParameter("status", status);\r
+               }\r
+               if(type != null){\r
+                       query.setParameter("type", type.getSimpleName());\r
+               }\r
+               \r
+               query.setParameter("name",name);\r
 \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("typeStatus").eq(status.getId()));\r
-                       }\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
+               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
-                       return (List<TypeDesignationBase>)query.getResultList();\r
                }\r
+               return defaultBeanInitializer.initializeAll((List<T>)query.list(), propertyPaths);\r
        }\r
 \r
        \r
@@ -368,7 +417,8 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
        }\r
        \r
        \r
-       public List<TaxonNameBase> searchNames(String genusOrUninomial,String infraGenericEpithet, String specificEpithet,      String infraSpecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {\r
+       public List<TaxonNameBase> searchNames(String genusOrUninomial,String infraGenericEpithet, String specificEpithet,      String infraSpecificEpithet, Rank rank, Integer pageSize,Integer pageNumber, List<OrderHint> orderHints,\r
+                       List<String> propertyPaths) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
                        Criteria criteria = getSession().createCriteria(TaxonNameBase.class);\r
@@ -413,8 +463,12 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                                        criteria.setFirstResult(0);\r
                                }\r
                        }\r
+                       \r
+                       addOrder(criteria, orderHints);\r
 \r
-                       return (List<TaxonNameBase>)criteria.list();\r
+                       List<TaxonNameBase> results = (List<TaxonNameBase>)criteria.list();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameBase.class,auditEvent.getRevisionNumber());\r
 \r
@@ -455,12 +509,14 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                                }\r
                        }\r
                        \r
-                       return (List<TaxonNameBase>)query.getResultList();\r
+                       List<TaxonNameBase> results = (List<TaxonNameBase>)query.getResultList();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
                }\r
        }\r
 \r
        public List<? extends TaxonNameBase<?,?>> findByName(String queryString, \r
-                       MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria) {\r
+                       MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria, List<String> propertyPaths) {\r
 \r
                Criteria crit = getSession().createCriteria(type);\r
                if (matchmode == MatchMode.EXACT) {\r
@@ -483,6 +539,111 @@ extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
                }\r
 \r
                List<? extends TaxonNameBase<?,?>> results = crit.list();\r
+               defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+               \r
                return results;\r
        }\r
+       \r
+       public List<RelationshipBase> getRelationships(Integer limit, Integer start) {\r
+               AuditEvent auditEvent = getAuditEventFromContext();\r
+               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+                   //FIXME only NameRelationships\r
+                       Criteria criteria = getSession().createCriteria(RelationshipBase.class);\r
+                   return (List<RelationshipBase>)criteria.list();\r
+               } else {\r
+                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());\r
+                       return (List<RelationshipBase>)query.getResultList();\r
+               }\r
+       }\r
+       \r
+       \r
+       public Integer countByName(String queryString, MatchMode matchmode, List<Criterion> criteria) {\r
+               //TODO improve performance\r
+               List<? extends TaxonNameBase<?,?>> results = findByName(queryString, matchmode, null, null, criteria, null);\r
+               return results.size();\r
+               \r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao#getUuidAndTitleCacheOfNames()\r
+        */\r
+       public List<UuidAndTitleCache> getUuidAndTitleCacheOfNames() {\r
+               String queryString = "SELECT uuid, fullTitleCache FROM TaxonNameBase";\r
+               \r
+               List<Object[]> result = getSession().createSQLQuery(queryString).list();\r
+                               \r
+               if(result.size() == 0){\r
+                       return null;\r
+               }else{\r
+                       List<UuidAndTitleCache> list = new ArrayList<UuidAndTitleCache>(result.size()); \r
+                       \r
+                       for (Object object : result){\r
+                               \r
+                               Object[] objectArray = (Object[]) object;\r
+                               \r
+                               UUID uuid = UUID.fromString((String) objectArray[0]);\r
+                               String titleCache = (String) objectArray[1];\r
+                               \r
+                               list.add(new UuidAndTitleCache(type, uuid, titleCache));\r
+                       }\r
+                       \r
+                       return list;    \r
+               }\r
+       }\r
+\r
+       public Integer countByName(Class<? extends TaxonNameBase> clazz,String queryString, MatchMode matchmode, List<Criterion> criteria) {\r
+        return super.countByParam(clazz, "nameCache", queryString, matchmode, criteria);\r
+       }\r
+\r
+       public List<TaxonNameBase> findByName(Class<? extends TaxonNameBase> clazz,     String queryString, MatchMode matchmode, List<Criterion> criteria,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,     List<String> propertyPaths) {\r
+               return super.findByParam(clazz, "nameCache", queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);\r
+       }\r
+       \r
+       public UUID delete (TaxonNameBase persistentObject){\r
+               Set<TaxonBase> taxonBases = persistentObject.getTaxonBases();\r
+               super.delete(persistentObject);\r
+                               \r
+               for (TaxonBase taxonBase: taxonBases){\r
+                       taxonDao.delete(taxonBase);\r
+               }\r
+               return persistentObject.getUuid();\r
+       }\r
+       \r
+       public List<ZoologicalName> getZoologicalNames(Integer limit, Integer start){\r
+               List <TaxonNameBase> names = new ArrayList<TaxonNameBase>();\r
+               List <ZoologicalName> zooNames = new ArrayList<ZoologicalName>();\r
+               names = super.list(ZoologicalName.class, limit, start);\r
+               for (TaxonNameBase name: names){\r
+                       zooNames.add((ZoologicalName)name);\r
+               }\r
+               return zooNames;\r
+       }\r
+       \r
+       public ZoologicalName findZoologicalNameByUUID(UUID uuid){\r
+               Criteria criteria = getSession().createCriteria(type);\r
+               if (uuid != null) {\r
+                       criteria.add(Restrictions.eq("uuid", uuid));\r
+               } else {\r
+                       logger.error("UUID is NULL");\r
+                       return null;\r
+               }\r
+               \r
+               List<? extends TaxonNameBase<?,?>> results = criteria.list();\r
+               if (results.size() == 1) {\r
+                       defaultBeanInitializer.initializeAll(results, null);\r
+                       TaxonNameBase<?, ?> taxonName = results.iterator().next();\r
+                       if (taxonName.isInstanceOf(ZoologicalName.class)) {\r
+                               ZoologicalName zoologicalName = CdmBase.deproxy(taxonName, ZoologicalName.class);\r
+                               return zoologicalName;\r
+                       } else {\r
+                               logger.warn("This UUID (" + uuid + ") does not belong to a ZoologicalName. It belongs to: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");\r
+                       }\r
+               } else if (results.size() > 1) {\r
+                       logger.warn("Multiple results for UUID: " + uuid);\r
+               } else if (results.size() == 0) {\r
+                       logger.warn("No results for UUID: " + uuid);\r
+               }\r
+               return null;\r
+       }\r
+\r
 }
\ No newline at end of file