method name harmonization
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / name / TaxonNameDaoHibernateImpl.java
index 5c36de4be1feda918d1649d89f4f3aa057da70ca..255a2b570aec3b1e3e0bffd1849773e064833d42 100644 (file)
  */\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.model.common.ReferencedEntityBase;\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.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
  *\r
  */\r
 @Repository\r
+@Qualifier("taxonNameDaoHibernateImpl")\r
 public class TaxonNameDaoHibernateImpl \r
-                       extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {\r
+extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {\r
+\r
+       @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(NonViralName name, HybridRelationshipType type) {\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 HybridRelationship relation where relation.relatedFrom = :name");\r
+                       } else {\r
+                               query = getSession().createQuery("select count(relation) from HybridRelationship relation where relation.relatedFrom = :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(HybridRelationship.class,auditEvent.getRevisionNumber());\r
+                       query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));\r
+                       query.addProjection(AuditEntity.id().count("id"));\r
+\r
+                       if(type != null) {\r
+                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+                       }\r
+\r
+                       return ((Long)query.getSingleResult()).intValue();\r
+               }\r
+       }\r
+       \r
+       public int countNames(String queryString) {\r
+               checkNotInPriorView("TaxonNameDaoHibernateImpl.countNames(String queryString)");\r
+        Criteria criteria = getSession().createCriteria(TaxonNameBase.class);\r
+        \r
+               if (queryString != null) {\r
+                       criteria.add(Restrictions.ilike("nameCache", queryString));\r
+               }\r
+               criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
+               \r
+               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
+                       Criteria criteria = getSession().createCriteria(TaxonNameBase.class);\r
+\r
+                       /**\r
+                        * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"\r
+                        * We need to convert nulls to NullRestrictions for now\r
+                        */\r
+                       if(genusOrUninomial != null) {\r
+                               criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("genusOrUninomial"));\r
+                       }\r
+\r
+                       if(infraGenericEpithet != null) {\r
+                               criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("infraGenericEpithet"));\r
+                       }\r
+\r
+                       if(specificEpithet != null) {\r
+                               criteria.add(Restrictions.eq("specificEpithet", specificEpithet));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("specificEpithet"));\r
+                       }\r
+\r
+                       if(infraSpecificEpithet != null) {\r
+                               criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("infraSpecificEpithet"));\r
+                       }\r
+\r
+                       if(rank != null) {\r
+                               criteria.add(Restrictions.eq("rank", rank));\r
+                       }\r
+\r
+                       criteria.setProjection(Projections.rowCount());\r
+                       return (Integer)criteria.uniqueResult();\r
+               } else {\r
+                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameBase.class,auditEvent.getRevisionNumber());\r
+\r
+                       if(genusOrUninomial != null) {\r
+                               query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));\r
+                       } else {\r
+                               query.add(AuditEntity.property("genusOrUninomial").isNull());\r
+                       }\r
+\r
+                       if(infraGenericEpithet != null) {\r
+                               query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));\r
+                       } else {\r
+                               query.add(AuditEntity.property("infraGenericEpithet").isNull());\r
+                       }\r
+\r
+                       if(specificEpithet != null) {\r
+                               query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));\r
+                       } else {\r
+                               query.add(AuditEntity.property("specificEpithet").isNull());\r
+                       }\r
+\r
+                       if(infraSpecificEpithet != null) {\r
+                               query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));\r
+                       } else {\r
+                               query.add(AuditEntity.property("infraSpecificEpithet").isNull());\r
+                       }\r
+\r
+                       if(rank != null) {\r
+                               query.add(AuditEntity.relatedId("rank").eq(rank.getId()));\r
+                       }\r
+\r
+                       query.addProjection(AuditEntity.id().count("id"));\r
+                       return ((Long)query.getSingleResult()).intValue();\r
+               }\r
+       }\r
+\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." + direction +" = :name");\r
+                       } else {\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(direction.toString()).eq(name.getId()));\r
+                       query.addProjection(AuditEntity.id().count("id"));\r
+\r
+                       if(type != null) {\r
+                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+                       }\r
+\r
+                       return ((Long)query.getSingleResult()).intValue();\r
+               }\r
+       }\r
+\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
+                       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(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
+                       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
+\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
+                       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
+                       \r
+                       if(type != null) {\r
+                               query.add(AuditEntity.relatedId("type").eq(type.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
+                       }\r
+\r
+                       List<HybridRelationship> results =  (List<HybridRelationship>)query.getResultList();\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
+               }\r
+       }\r
+\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
+                       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
+\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
+                       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(direction.toString()).eq(name.getId()));\r
+\r
+                       if(type != null) {\r
+                               query.add(AuditEntity.relatedId("type").eq(type.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
+                       }\r
+\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
+               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(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 defaultBeanInitializer.initializeAll((List<T>)query.list(), propertyPaths);\r
+       }\r
+\r
+       \r
+       public List<TaxonNameBase<?,?>> searchNames(String queryString, MatchMode matchMode, Integer pageSize, Integer pageNumber) {\r
+               checkNotInPriorView("TaxonNameDaoHibernateImpl.searchNames(String queryString, Integer pageSize, Integer pageNumber)");\r
+               Criteria criteria = getSession().createCriteria(TaxonNameBase.class);\r
+\r
+               if (queryString != null) {\r
+                       criteria.add(Restrictions.ilike("nameCache", queryString));\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
+               List<TaxonNameBase<?,?>> results = criteria.list();\r
+               return results;\r
+       }\r
+\r
+       \r
+       public List<TaxonNameBase<?,?>> searchNames(String queryString, Integer pageSize, Integer pageNumber) {\r
+               return searchNames(queryString, MatchMode.BEGINNING, pageSize, pageNumber);\r
+       }\r
+       \r
+       \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
+\r
+                       /**\r
+                        * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"\r
+                        * We need to convert nulls to NullRestrictions for now\r
+                        */\r
+                       if(genusOrUninomial != null) {\r
+                               criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("genusOrUninomial"));\r
+                       }\r
+\r
+                       if(infraGenericEpithet != null) {\r
+                               criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("infraGenericEpithet"));\r
+                       }\r
+\r
+                       if(specificEpithet != null) {\r
+                               criteria.add(Restrictions.eq("specificEpithet", specificEpithet));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("specificEpithet"));\r
+                       }\r
+\r
+                       if(infraSpecificEpithet != null) {\r
+                               criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));\r
+                       } else {\r
+                               criteria.add(Restrictions.isNull("infraSpecificEpithet"));\r
+                       }\r
+                       \r
+                       if(rank != null) {\r
+                           criteria.add(Restrictions.eq("rank", rank));\r
+                       }\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
+                       addOrder(criteria, orderHints);\r
+\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
+                       if(genusOrUninomial != null) {\r
+                               query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));\r
+                       } else {\r
+                               query.add(AuditEntity.property("genusOrUninomial").isNull());\r
+                       }\r
+\r
+                       if(infraGenericEpithet != null) {\r
+                               query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));\r
+                       } else {\r
+                               query.add(AuditEntity.property("infraGenericEpithet").isNull());\r
+                       }\r
+\r
+                       if(specificEpithet != null) {\r
+                               query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));\r
+                       } else {\r
+                               query.add(AuditEntity.property("specificEpithet").isNull());\r
+                       }\r
+\r
+                       if(infraSpecificEpithet != null) {\r
+                               query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));\r
+                       } else {\r
+                               query.add(AuditEntity.property("infraSpecificEpithet").isNull());\r
+                       }\r
+\r
+                       if(rank != null) {\r
+                               query.add(AuditEntity.relatedId("rank").eq(rank.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
+                       }\r
+                       \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, List<String> propertyPaths) {\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
+               crit.addOrder(Order.asc("nameCache"));\r
+\r
+               if(pageSize != null) {\r
+                       crit.setMaxResults(pageSize);\r
+                       if(pageNumber != null) {\r
+                               crit.setFirstResult(pageNumber * pageSize);\r
+                       }\r
+               }\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