cleanup
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / occurrence / OccurrenceDaoHibernateImpl.java
index 59c170c6642360a35be63b495844a4dac1420256..6c33f68e1f6e260f3e905cd7c204ec968d52995e 100644 (file)
@@ -33,6 +33,7 @@ import org.springframework.stereotype.Repository;
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
 import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;\r
+import eu.etaxonomy.cdm.model.location.Point;\r
 import eu.etaxonomy.cdm.model.media.Media;\r
 import eu.etaxonomy.cdm.model.molecular.DnaSample;\r
 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
@@ -56,18 +57,20 @@ import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;\r
 import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;\r
 import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;\r
+import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;\r
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;\r
 import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
 import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
 \r
 /**\r
  * @author a.babadshanjan\r
- * @created 01.09.2008\r
+ * @since 01.09.2008\r
  */\r
 @Repository\r
-public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrObservationBase> implements IOccurrenceDao {\r
+public class OccurrenceDaoHibernateImpl\r
+          extends IdentifiableDaoBase<SpecimenOrObservationBase>\r
+          implements IOccurrenceDao {\r
 \r
-    @SuppressWarnings("unused")\r
     private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\r
 \r
     @Autowired\r
@@ -88,19 +91,19 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
     }\r
 \r
     @Override\r
-    public int countDerivationEvents(SpecimenOrObservationBase occurence) {\r
+    public long countDerivationEvents(SpecimenOrObservationBase occurence) {\r
         checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");\r
         Query query = getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");\r
         query.setParameter("occurence", occurence);\r
 \r
-        return ((Long)query.uniqueResult()).intValue();\r
+        return (Long)query.uniqueResult();\r
     }\r
 \r
     @Override\r
-    public int countDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase) {\r
+    public long countDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase) {\r
         AuditEvent auditEvent = getAuditEventFromContext();\r
         if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-            Criteria criteria = getSession().createCriteria(DeterminationEvent.class);\r
+            Criteria criteria = getCriteria(DeterminationEvent.class);\r
             if(occurrence != null) {\r
                 criteria.add(Restrictions.eq("identifiedUnit",occurrence));\r
             }\r
@@ -110,9 +113,9 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             }\r
 \r
             criteria.setProjection(Projections.rowCount());\r
-            return ((Number)criteria.uniqueResult()).intValue();\r
+            return (Long)criteria.uniqueResult();\r
         } else {\r
-            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());\r
+            AuditQuery query = makeAuditQuery(DeterminationEvent.class,auditEvent);\r
 \r
             if(occurrence != null) {\r
                 query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));\r
@@ -123,41 +126,36 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             }\r
             query.addProjection(AuditEntity.id().count());\r
 \r
-            return ((Long)query.getSingleResult()).intValue();\r
+            return (Long)query.getSingleResult();\r
         }\r
     }\r
 \r
     @Override\r
-    public int countMedia(SpecimenOrObservationBase occurence) {\r
+    public long countMedia(SpecimenOrObservationBase occurence) {\r
         checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");\r
-        Query query = getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");\r
+        Query query = getSession().createQuery("SELECT count(media) FROM SpecimenOrObservationBase occurence JOIN occurence.media media WHERE occurence = :occurence");\r
         query.setParameter("occurence", occurence);\r
 \r
-        return ((Long)query.uniqueResult()).intValue();\r
+        return (Long)query.uniqueResult();\r
     }\r
 \r
     @Override\r
     public List<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {\r
         checkNotInPriorView("OccurrenceDaoHibernateImpl.getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber)");\r
-        Query query = getSession().createQuery("select distinct derivationEvent from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");\r
+        Query query = getSession().createQuery("SELECT DISTINCT derivationEvent FROM DerivationEvent derivationEvent JOIN derivationEvent.originals occurence WHERE occurence = :occurence");\r
         query.setParameter("occurence", occurence);\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
+        addPageSizeAndNumber(query, pageSize, pageNumber);\r
 \r
+        @SuppressWarnings("unchecked")\r
         List<DerivationEvent> result = query.list();\r
         defaultBeanInitializer.initializeAll(result, propertyPaths);\r
         return result;\r
     }\r
 \r
     @Override\r
-    public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
+    public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurrence,\r
+            TaxonBase taxonBase, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
         AuditEvent auditEvent = getAuditEventFromContext();\r
         if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
             Criteria criteria = getSession().createCriteria(DeterminationEvent.class);\r
@@ -169,14 +167,9 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
                 criteria.add(Restrictions.eq("taxon",taxonBase));\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
+            addPageSizeAndNumber(criteria, pageSize, pageNumber);\r
+\r
+            @SuppressWarnings("unchecked")\r
             List<DeterminationEvent> result = criteria.list();\r
             defaultBeanInitializer.initializeAll(result, propertyPaths);\r
             return result;\r
@@ -189,14 +182,9 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             if(taxonBase != null) {\r
                 query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));\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
+            addPageSizeAndNumber(query, pageSize, pageNumber);\r
+\r
+            @SuppressWarnings("unchecked")\r
             List<DeterminationEvent> result = query.getResultList();\r
             defaultBeanInitializer.initializeAll(result, propertyPaths);\r
             return result;\r
@@ -204,20 +192,19 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
     }\r
 \r
     @Override\r
-    public List<Media> getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
+    public List<Media> getMedia(SpecimenOrObservationBase occurence,\r
+            Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
         checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");\r
-        Query query = getSession().createQuery("select media from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");\r
+        Query query = getSession().createQuery(\r
+                "   SELECT media "\r
+                + " FROM SpecimenOrObservationBase occurence "\r
+                + " JOIN occurence.media media "\r
+                + " WHERE occurence = :occurence");\r
         query.setParameter("occurence", occurence);\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
+        addPageSizeAndNumber(query, pageSize, pageNumber);\r
 \r
+        @SuppressWarnings("unchecked")\r
         List<Media> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
@@ -257,86 +244,54 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
     }\r
 \r
     @Override\r
-    public int count(Class<? extends SpecimenOrObservationBase> clazz, TaxonName determinedAs) {\r
+    public long count(Class<? extends SpecimenOrObservationBase> clazz,        TaxonName determinedAs) {\r
 \r
-        Criteria criteria = null;\r
-        if(clazz == null) {\r
-            criteria = getSession().createCriteria(type);\r
-        } else {\r
-            criteria = getSession().createCriteria(clazz);\r
-        }\r
+        Criteria criteria = getCriteria(clazz);\r
 \r
         criteria.createCriteria("determinations").add(Restrictions.eq("taxonName", determinedAs));\r
         criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
-        return ((Number)criteria.uniqueResult()).intValue();\r
+        return (Long)criteria.uniqueResult();\r
     }\r
 \r
     @Override\r
-    public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonName determinedAs, Integer limit, Integer start,        List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        Criteria criteria = null;\r
-        if(clazz == null) {\r
-            criteria = getSession().createCriteria(type);\r
-        } else {\r
-            criteria = getSession().createCriteria(clazz);\r
-        }\r
+    public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonName determinedAs,\r
+            Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+        Criteria criteria = getCriteria(clazz);\r
 \r
         criteria.createCriteria("determinations").add(Restrictions.eq("taxonName", determinedAs));\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                criteria.setFirstResult(start);\r
-            } else {\r
-                criteria.setFirstResult(0);\r
-            }\r
-            criteria.setMaxResults(limit);\r
-        }\r
-\r
+        addPageSizeAndNumber(criteria, pageSize, pageNumber);\r
         addOrder(criteria,orderHints);\r
 \r
-        @SuppressWarnings("unchecked")\r
+        @SuppressWarnings({ "unchecked", "rawtypes" })\r
         List<SpecimenOrObservationBase> results = criteria.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
 \r
     @Override\r
-    public int count(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs) {\r
+    public long count(Class<? extends SpecimenOrObservationBase> clazz,        TaxonBase determinedAs) {\r
 \r
-        Criteria criteria = null;\r
-        if(clazz == null) {\r
-            criteria = getSession().createCriteria(type);\r
-        } else {\r
-            criteria = getSession().createCriteria(clazz);\r
-        }\r
+        Criteria criteria = getCriteria(clazz);\r
 \r
         criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));\r
         criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
-        return ((Number)criteria.uniqueResult()).intValue();\r
+        return (Long)criteria.uniqueResult();\r
     }\r
 \r
+\r
     @Override\r
-    public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs, Integer limit, Integer start,        List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        Criteria criteria = null;\r
-        if(clazz == null) {\r
-            criteria = getSession().createCriteria(type);\r
-        } else {\r
-            criteria = getSession().createCriteria(clazz);\r
-        }\r
+    public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs,\r
+            Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
 \r
-        criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));\r
+        Criteria criteria = getCriteria(clazz);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                criteria.setFirstResult(start);\r
-            } else {\r
-                criteria.setFirstResult(0);\r
-            }\r
-            criteria.setMaxResults(limit);\r
-        }\r
+        criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));\r
 \r
+        addPageSizeAndNumber(criteria, pageSize, pageNumber);\r
         addOrder(criteria,orderHints);\r
 \r
-        @SuppressWarnings("unchecked")\r
+        @SuppressWarnings({ "unchecked", "rawtypes" })\r
         List<SpecimenOrObservationBase> results = criteria.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
@@ -356,14 +311,16 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             projectionList.add(Projections.property("titleCache"));\r
             criteria.setProjection(projectionList);\r
 \r
+            @SuppressWarnings("unchecked")\r
             List<Object[]> result = criteria.list();\r
             List<UuidAndTitleCache<SpecimenOrObservationBase>> uuidAndTitleCacheList = new ArrayList<>();\r
             for(Object[] object : result){\r
-                uuidAndTitleCacheList.add(new UuidAndTitleCache<SpecimenOrObservationBase>((UUID) object[0],(Integer) object[1], (String) object[2]));\r
+                uuidAndTitleCacheList.add(new UuidAndTitleCache<>((UUID) object[0],(Integer) object[1], (String) object[2]));\r
             }\r
             return uuidAndTitleCacheList;\r
+        }else{\r
+            return Collections.emptyList();\r
         }\r
-        return Collections.emptyList();\r
     }\r
 \r
     @Override\r
@@ -378,12 +335,14 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             List<T> results = criteria.list();\r
             defaultBeanInitializer.initializeAll(results, propertyPaths);\r
             return results;\r
+        }else{\r
+            return Collections.emptyList();\r
         }\r
-        return Collections.emptyList();\r
     }\r
 \r
     private <T extends SpecimenOrObservationBase> Criteria createFindOccurrenceCriteria(Class<T> clazz, String queryString,\r
-            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, TaxonName associatedTaxonName, MatchMode matchmode, Integer limit,\r
+            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
+            TaxonName associatedTaxonName, MatchMode matchmode, Integer limit,\r
             Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
         Criteria criteria = null;\r
 \r
@@ -416,7 +375,7 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
         }\r
 \r
         //recordBasis/SpecimenOrObservationType\r
-        Set<SpecimenOrObservationType> typeAndSubtypes = new HashSet<SpecimenOrObservationType>();\r
+        Set<SpecimenOrObservationType> typeAndSubtypes = new HashSet<>();\r
         if(recordBasis==null){\r
             //add all types\r
             SpecimenOrObservationType[] values = SpecimenOrObservationType.values();\r
@@ -430,7 +389,7 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
         }\r
         criteria.add(Restrictions.in("recordBasis", typeAndSubtypes));\r
 \r
-        Set<UUID> associationUuids = new HashSet<UUID>();\r
+        Set<UUID> associationUuids = new HashSet<>();\r
         //taxon associations\r
         if(associatedTaxon!=null){\r
             List<UuidAndTitleCache<SpecimenOrObservationBase>> associatedTaxaList = listUuidAndTitleCacheByAssociatedTaxon(clazz, associatedTaxon, limit, start, orderHints);\r
@@ -444,7 +403,7 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
         else if(associatedTaxonName!=null){\r
             List<? extends SpecimenOrObservationBase> associatedTaxaList = listByAssociatedTaxonName(clazz, associatedTaxonName, limit, start, orderHints, propertyPaths);\r
             if(associatedTaxaList!=null){\r
-                for (SpecimenOrObservationBase specimenOrObservationBase : associatedTaxaList) {\r
+                for (SpecimenOrObservationBase<?> specimenOrObservationBase : associatedTaxaList) {\r
                     associationUuids.add(specimenOrObservationBase.getUuid());\r
                 }\r
             }\r
@@ -474,41 +433,43 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
 \r
 \r
     @Override\r
-    public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,\r
+    public <T extends SpecimenOrObservationBase> long countOccurrences(Class<T> clazz, String queryString,\r
             String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, TaxonName associatedTaxonName,\r
             MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
         Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,\r
                 associatedTaxon, associatedTaxonName, matchmode, limit, start, orderHints, propertyPaths);\r
 \r
         if(criteria!=null){\r
-\r
             criteria.setProjection(Projections.rowCount());\r
-\r
-            return ((Number)criteria.uniqueResult()).intValue();\r
+            return (Long)criteria.uniqueResult();\r
+        }else{\r
+            return 0;\r
         }\r
-        return 0;\r
     }\r
 \r
     @Override\r
     public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache(Integer limit, String pattern) {\r
-        List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<UuidAndTitleCache<DerivedUnit>>();\r
+        List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<>();\r
         Session session = getSession();\r
+        String hql = "SELECT uuid, id, titleCache "\r
+                + " FROM " + type.getSimpleName()\r
+                + " WHERE NOT dtype = " + FieldUnit.class.getSimpleName();\r
         Query query;\r
         if (pattern != null){\r
-            query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where NOT dtype = " + FieldUnit.class.getSimpleName() +" AND titleCache like :pattern");\r
             pattern = pattern.replace("*", "%");\r
             pattern = pattern.replace("?", "_");\r
             pattern = pattern + "%";\r
+            query = session.createQuery(hql +" AND titleCache like :pattern");\r
             query.setParameter("pattern", pattern);\r
         } else {\r
-            query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() +" where NOT dtype = " + FieldUnit.class.getSimpleName());\r
+            query = session.createQuery(hql);\r
         }\r
         if (limit != null){\r
            query.setMaxResults(limit);\r
         }\r
 \r
-\r
-\r
+        @SuppressWarnings("unchecked")\r
         List<Object[]> result = query.list();\r
 \r
         for(Object[] object : result){\r
@@ -520,11 +481,12 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
 \r
     @Override\r
     public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {\r
-        List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<UuidAndTitleCache<FieldUnit>>();\r
+        List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<>();\r
         Session session = getSession();\r
 \r
         Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where dtype = " + FieldUnit.class.getSimpleName());\r
 \r
+        @SuppressWarnings("unchecked")\r
         List<Object[]> result = query.list();\r
 \r
         for(Object[] object : result){\r
@@ -537,9 +499,12 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
     @Override\r
     public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxonName(Class<T> type,\r
             TaxonName associatedTaxonName, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();\r
+\r
+        @SuppressWarnings("rawtypes")\r
+        Set<SpecimenOrObservationBase> setOfAll = new HashSet<>();\r
 \r
         // A Taxon name may be referenced by the DeterminationEvent of the SpecimenOrObservationBase\r
+        @SuppressWarnings("rawtypes")\r
         List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxonName, null, 0, null, null);\r
         setOfAll.addAll(byDetermination);\r
 \r
@@ -549,25 +514,14 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
         }\r
 \r
         String queryString =\r
-            "select sob " +\r
-            " from SpecimenOrObservationBase sob" +\r
-            " where sob in (:setOfAll)";\r
+            "SELECT sob " +\r
+            " FROM SpecimenOrObservationBase sob" +\r
+            " WHERE sob in (:setOfAll)";\r
 \r
         if(type != null && !type.equals(SpecimenOrObservationBase.class)){\r
-            queryString += " and sob.class = :type";\r
-        }\r
-\r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " order by ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
+            queryString += " AND sob.class = :type";\r
         }\r
+        queryString += orderByClause("sob", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameterList("setOfAll", setOfAll);\r
@@ -576,28 +530,48 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             query.setParameter("type", type.getSimpleName());\r
         }\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
-\r
+        addLimitAndStart(query, limit, start);\r
 \r
+        @SuppressWarnings("unchecked")\r
         List<T> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
 \r
+    private List<SpecimenNodeWrapper> querySpecimen(Query query, List<UUID> taxonNodeUuids,\r
+            Integer limit, Integer start){\r
+        query.setParameterList("taxonNodeUuids", taxonNodeUuids);\r
+\r
+        addLimitAndStart(query, limit, start);\r
+\r
+        List<SpecimenNodeWrapper> list = new ArrayList<>();\r
+        @SuppressWarnings("unchecked")\r
+        List<Object[]> result = query.list();\r
+        for(Object[] object : result){\r
+            SpecimenNodeWrapper wrapper = new SpecimenNodeWrapper(\r
+                    new UuidAndTitleCache<>(\r
+                            (UUID) object[0],\r
+                            (Integer) object[1],\r
+                            (String) object[2]),\r
+                    (SpecimenOrObservationType)object[3],\r
+                    new TaxonNodeDto((TaxonNode)object[4]));\r
+            if(object.length>5) {\r
+                wrapper.setTaxonDescriptionUuid((UUID)object[5]);\r
+            }\r
+            list.add(wrapper);\r
+        }\r
+        return list;\r
+    }\r
+\r
     private List<SpecimenNodeWrapper> queryIndividualAssociatedSpecimen(List<UUID> taxonNodeUuids,\r
-            Integer limit, Integer start, List<OrderHint> orderHintss){\r
+            Integer limit, Integer start){\r
         String queryString =  "SELECT "\r
                 + "de.associatedSpecimenOrObservation.uuid, "\r
                 + "de.associatedSpecimenOrObservation.id, "\r
                 + "de.associatedSpecimenOrObservation.titleCache, "\r
-                + "tn "\r
+                + "de.associatedSpecimenOrObservation.recordBasis, "\r
+                + "tn, "\r
+                + "d.uuid "\r
                 + "FROM DescriptionElementBase AS de "\r
                 + "LEFT JOIN de.inDescription AS d "\r
                 + "LEFT JOIN d.taxon AS t "\r
@@ -606,37 +580,16 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
                 + "AND tn.uuid in (:taxonNodeUuids) "\r
                 ;\r
         Query query = getSession().createQuery(queryString);\r
-\r
-        query.setParameterList("taxonNodeUuids", taxonNodeUuids);\r
-\r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
-\r
-        List<SpecimenNodeWrapper> list = new ArrayList<>();\r
-        List<Object[]> result = query.list();\r
-        for(Object[] object : result){\r
-            list.add(new SpecimenNodeWrapper(\r
-                    new UuidAndTitleCache<SpecimenOrObservationBase>(\r
-                            (UUID) object[0],\r
-                            (Integer) object[1],\r
-                            (String) object[2]),\r
-                    (TaxonNode)object[3]));\r
-        }\r
-        return list;\r
+        return querySpecimen(query, taxonNodeUuids, limit, start);\r
     }\r
 \r
     private List<SpecimenNodeWrapper> queryTypeSpecimen(List<UUID> taxonNodeUuids,\r
-            Integer limit, Integer start, List<OrderHint> orderHints){\r
+            Integer limit, Integer start){\r
         String queryString =  "SELECT "\r
                 + "td.typeSpecimen.uuid, "\r
                 + "td.typeSpecimen.id, "\r
                 + "td.typeSpecimen.titleCache, "\r
+                + "td.typeSpecimen.recordBasis, "\r
                 + "tn "\r
                 + "FROM SpecimenTypeDesignation AS td "\r
                 + "LEFT JOIN td.typifiedNames AS tn "\r
@@ -645,37 +598,16 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
                 + "WHERE tn.uuid in (:taxonNodeUuids) "\r
                 ;\r
         Query query = getSession().createQuery(queryString);\r
-\r
-        query.setParameterList("taxonNodeUuids", taxonNodeUuids);\r
-\r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
-\r
-        List<SpecimenNodeWrapper> list = new ArrayList<>();\r
-        List<Object[]> result = query.list();\r
-        for(Object[] object : result){\r
-            list.add(new SpecimenNodeWrapper(\r
-                    new UuidAndTitleCache<SpecimenOrObservationBase>(\r
-                            (UUID) object[0],\r
-                            (Integer) object[1],\r
-                            (String) object[2]),\r
-                    (TaxonNode)object[3]));\r
-        }\r
-        return list;\r
+        return querySpecimen(query, taxonNodeUuids, limit, start);\r
     }\r
 \r
     private List<SpecimenNodeWrapper> queryTaxonDeterminations(List<UUID> taxonNodeUuids,\r
-            Integer limit, Integer start, List<OrderHint> orderHints){\r
+            Integer limit, Integer start){\r
         String queryString =  "SELECT "\r
                 + "det.identifiedUnit.uuid, "\r
                 + "det.identifiedUnit.id, "\r
                 + "det.identifiedUnit.titleCache, "\r
+                + "det.identifiedUnit.recordBasis, "\r
                 + "tn "\r
                 + "FROM DeterminationEvent AS det "\r
                 + "LEFT JOIN det.taxon AS t "\r
@@ -683,37 +615,16 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
                 + "WHERE tn.uuid in (:taxonNodeUuids) "\r
                 ;\r
         Query query = getSession().createQuery(queryString);\r
-\r
-        query.setParameterList("taxonNodeUuids", taxonNodeUuids);\r
-\r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
-\r
-        List<SpecimenNodeWrapper> list = new ArrayList<>();\r
-        List<Object[]> result = query.list();\r
-        for(Object[] object : result){\r
-            list.add(new SpecimenNodeWrapper(\r
-                    new UuidAndTitleCache<SpecimenOrObservationBase>(\r
-                            (UUID) object[0],\r
-                            (Integer) object[1],\r
-                            (String) object[2]),\r
-                    (TaxonNode)object[3]));\r
-        }\r
-        return list;\r
+        return querySpecimen(query, taxonNodeUuids, limit, start);\r
     }\r
 \r
     private List<SpecimenNodeWrapper> queryTaxonNameDeterminations(List<UUID> taxonNodeUuids,\r
-            Integer limit, Integer start, List<OrderHint> orderHints){\r
+            Integer limit, Integer start){\r
         String queryString =  "SELECT "\r
                 + "det.identifiedUnit.uuid, "\r
                 + "det.identifiedUnit.id, "\r
                 + "det.identifiedUnit.titleCache, "\r
+                + "det.identifiedUnit.recordBasis, "\r
                 + "tn "\r
                 + "FROM DeterminationEvent AS det "\r
                 + "LEFT JOIN det.taxonName AS n "\r
@@ -722,55 +633,37 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
                 + "WHERE tn.uuid in (:taxonNodeUuids) "\r
                 ;\r
         Query query = getSession().createQuery(queryString);\r
-\r
-        query.setParameterList("taxonNodeUuids", taxonNodeUuids);\r
-\r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
-\r
-        List<SpecimenNodeWrapper> list = new ArrayList<>();\r
-        List<Object[]> result = query.list();\r
-        for(Object[] object : result){\r
-            list.add(new SpecimenNodeWrapper(\r
-                    new UuidAndTitleCache<SpecimenOrObservationBase>(\r
-                            (UUID) object[0],\r
-                            (Integer) object[1],\r
-                            (String) object[2]),\r
-                    (TaxonNode)object[3]));\r
-        }\r
-        return list;\r
+        return querySpecimen(query, taxonNodeUuids, limit, start);\r
     }\r
 \r
     @Override\r
-    public List<SpecimenNodeWrapper> listUuidAndTitleCacheByAssociatedTaxon(List<UUID> taxonNodeUuids,\r
-            Integer limit, Integer start, List<OrderHint> orderHints){\r
+    public Collection<SpecimenNodeWrapper> listUuidAndTitleCacheByAssociatedTaxon(List<UUID> taxonNodeUuids,\r
+            Integer limit, Integer start){\r
 \r
-        List<SpecimenNodeWrapper> list = new ArrayList<>();\r
-        list.addAll(queryIndividualAssociatedSpecimen(taxonNodeUuids, limit, start, orderHints));\r
-        list.addAll(queryTaxonDeterminations(taxonNodeUuids, limit, start, orderHints));\r
-        list.addAll(queryTaxonNameDeterminations(taxonNodeUuids, limit, start, orderHints));\r
-        list.addAll(queryTypeSpecimen(taxonNodeUuids, limit, start, orderHints));\r
+        Set<SpecimenNodeWrapper> testSet = new HashSet();\r
 \r
-        return list;\r
+        testSet.addAll(queryIndividualAssociatedSpecimen(taxonNodeUuids, limit, start));\r
+        testSet.addAll(queryTaxonDeterminations(taxonNodeUuids, limit, start));\r
+        testSet.addAll(queryTaxonNameDeterminations(taxonNodeUuids, limit, start));\r
+        testSet.addAll(queryTypeSpecimen(taxonNodeUuids, limit, start));\r
+\r
+        Collection<SpecimenNodeWrapper> wrappers = new HashSet<>();\r
+        wrappers.addAll(testSet);\r
+        return wrappers;\r
     }\r
 \r
     @Override\r
     public <T extends SpecimenOrObservationBase> List<UuidAndTitleCache<SpecimenOrObservationBase>> listUuidAndTitleCacheByAssociatedTaxon(Class<T> clazz, Taxon associatedTaxon,\r
             Integer limit, Integer start, List<OrderHint> orderHints){\r
-        Query query = createSpecimenQuery("sob.uuid, sob.id, sob.titleCache", clazz, associatedTaxon, limit, start, orderHints, null);\r
+        Query query = createSpecimenQuery("sob.uuid, sob.id, sob.titleCache", clazz, associatedTaxon, limit, start, orderHints);\r
         if(query==null){\r
             return Collections.emptyList();\r
         }\r
         List<UuidAndTitleCache<SpecimenOrObservationBase>> list = new ArrayList<>();\r
+        @SuppressWarnings("unchecked")\r
         List<Object[]> result = query.list();\r
         for(Object[] object : result){\r
-            list.add(new UuidAndTitleCache<SpecimenOrObservationBase>((UUID) object[0],(Integer) object[1], (String) object[2]));\r
+            list.add(new UuidAndTitleCache<>((UUID) object[0],(Integer) object[1], (String) object[2]));\r
         }\r
         return list;\r
     }\r
@@ -778,18 +671,19 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
     @Override\r
     public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> clazz,\r
             Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        Query query = createSpecimenQuery("sob", clazz, associatedTaxon, limit, start, orderHints, propertyPaths);\r
+        Query query = createSpecimenQuery("sob", clazz, associatedTaxon, limit, start, orderHints);\r
         if(query==null){\r
             return Collections.emptyList();\r
         }\r
+        @SuppressWarnings("unchecked")\r
         List<T> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
 \r
     private <T extends SpecimenOrObservationBase> Query createSpecimenQuery(String select, Class<T> clazz,\r
-            Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){\r
-        Set<SpecimenOrObservationBase> setOfAll = new HashSet<>();\r
+            Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints){\r
+//        Set<SpecimenOrObservationBase> setOfAll = new HashSet<>();\r
         Set<Integer> setOfAllIds = new HashSet<>();\r
 \r
         Criteria criteria = null;\r
@@ -848,7 +742,9 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
         for(HomotypicalGroup homotypicalGroup :  associatedTaxon.getHomotypicSynonymyGroups()) {\r
             List<SpecimenTypeDesignation> byHomotypicalGroup = homotypicalGroupDao.getTypeDesignations(homotypicalGroup, SpecimenTypeDesignation.class, null, null, 0, null);\r
             for (SpecimenTypeDesignation specimenTypeDesignation : byHomotypicalGroup) {\r
-                setOfAll.add(specimenTypeDesignation.getTypeSpecimen());\r
+                if (specimenTypeDesignation.getTypeSpecimen() != null){\r
+                    setOfAllIds.add(specimenTypeDesignation.getTypeSpecimen().getId());\r
+                }\r
             }\r
         }\r
 \r
@@ -885,111 +781,59 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             query.setParameter("type", clazz.getSimpleName());\r
         }\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
+        addLimitAndStart(query, limit, start);\r
 \r
         return query;\r
     }\r
 \r
     @Override\r
     public Collection<SpecimenOrObservationBase> listBySpecimenOrObservationType(SpecimenOrObservationType type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        String queryString = "FROM SpecimenOrObservationBase specimens WHERE specimens.recordBasis = :type";\r
+        String queryString = "FROM SpecimenOrObservationBase specimens "\r
+                + " WHERE specimens.recordBasis = :type ";\r
 \r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " order by ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "specimens." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
-        }\r
+        queryString += orderByClause("specimens", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameter("type", type);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
+        addLimitAndStart(query, limit, start);\r
 \r
-        List results = query.list();\r
+        @SuppressWarnings({ "unchecked", "rawtypes" })\r
+        List<SpecimenOrObservationBase> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
 \r
+\r
     @Override\r
     public Collection<DeterminationEvent> listDeterminationEvents(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        String queryString = "FROM DeterminationEvent determination WHERE determination.identifiedUnit = :specimen";\r
+        String queryString = "FROM DeterminationEvent determination "\r
+                + " WHERE determination.identifiedUnit = :specimen";\r
 \r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " order by ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "determination." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
-        }\r
+        queryString += orderByClause("determination", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameter("specimen", specimen);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
+        addLimitAndStart(query, limit, start);\r
 \r
-        List results = query.list();\r
+        @SuppressWarnings("unchecked")\r
+        List<DeterminationEvent> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
 \r
     @Override\r
     public Collection<SpecimenTypeDesignation> listTypeDesignations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        String queryString = "FROM SpecimenTypeDesignation designations WHERE designations.typeSpecimen = :specimen";\r
+        String queryString = "FROM SpecimenTypeDesignation designations "\r
+                + " WHERE designations.typeSpecimen = :specimen";\r
 \r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " ORDER BY ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "designations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
-        }\r
+        queryString += orderByClause("designations", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameter("specimen", specimen);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
+        addLimitAndStart(query, limit, start);\r
 \r
         @SuppressWarnings("unchecked")\r
         List<SpecimenTypeDesignation> results = query.list();\r
@@ -997,36 +841,21 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
         return results;\r
     }\r
 \r
+\r
     @Override\r
     public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
         //DISTINCT is necessary if more than one description exists for a taxon because we create the cross product of all taxon descriptions and description elements\r
         String queryString = "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";\r
 \r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " order by ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "associations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
-        }\r
+        queryString += orderByClause("associations", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameter("specimen", specimen);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
+        addLimitAndStart(query, limit, start);\r
 \r
-        List results = query.list();\r
+        @SuppressWarnings("unchecked")\r
+        List<IndividualsAssociation> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
@@ -1034,33 +863,18 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
     @Override\r
     public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
         //DISTINCT is necessary if more than one description exists for a taxon because we create the cross product of all taxon descriptions and description elements\r
-        String queryString = "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";\r
+        String queryString = "FROM DescriptionBase descriptions "\r
+                + " WHERE descriptions.describedSpecimenOrObservation = :specimen";\r
 \r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " order by ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
-        }\r
+        queryString += orderByClause("descriptions", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameter("specimen", specimen);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
-            }\r
-            query.setMaxResults(limit);\r
-        }\r
+        addLimitAndStart(query, limit, start);\r
 \r
-        List results = query.list();\r
+        @SuppressWarnings("unchecked")\r
+        List<DescriptionBase<?>> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
@@ -1069,36 +883,119 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
      * {@inheritDoc}\r
      */\r
     @Override\r
-    public List<FieldUnit> getFieldUnitsForGatheringEvent(UUID gatheringEventUuid, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        String queryString = "FROM SpecimenOrObservationBase s WHERE s.gatheringEvent.uuid = :gatheringEventUuid";\r
+    public List<FieldUnit> findFieldUnitsForGatheringEvent(UUID gatheringEventUuid, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+        String queryString = "FROM SpecimenOrObservationBase sob "\r
+                + "WHERE sob.gatheringEvent.uuid = :gatheringEventUuid";\r
 \r
-        if(orderHints != null && orderHints.size() > 0){\r
-            queryString += " order by ";\r
-            String orderStr = "";\r
-            for(OrderHint orderHint : orderHints){\r
-                if(orderStr.length() > 0){\r
-                    orderStr += ", ";\r
-                }\r
-                queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
-            }\r
-            queryString += orderStr;\r
-        }\r
+        queryString += orderByClause("sob", orderHints);\r
 \r
         Query query = getSession().createQuery(queryString);\r
         query.setParameter("gatheringEventUuid", gatheringEventUuid);\r
 \r
-        if(limit != null) {\r
-            if(start != null) {\r
-                query.setFirstResult(start);\r
-            } else {\r
-                query.setFirstResult(0);\r
+        addLimitAndStart(query, limit, start);\r
+\r
+        @SuppressWarnings("unchecked")\r
+        List<FieldUnit> results = query.list();\r
+        defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+        return results;\r
+    }\r
+\r
+    /**\r
+     *\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public DnaSample findByGeneticAccessionNumber(String accessionNumberString, List<String> propertyPaths) {\r
+        String queryString = "SELECT dnaSample FROM DnaSample as dnaSample join dnaSample.sequences as sequences WITH sequences.geneticAccessionNumber LIKE :accessionNumberString";\r
+        Query query = getSession().createQuery(queryString);\r
+        query.setParameter("accessionNumberString", accessionNumberString);\r
+        @SuppressWarnings("unchecked")\r
+        List<DnaSample> dnaSamples = query.list();\r
+        defaultBeanInitializer.initializeAll(dnaSamples, propertyPaths);\r
+\r
+\r
+        if (dnaSamples.isEmpty()){\r
+            logger.debug("there is no dnaSample for genetic accession number " + accessionNumberString + " this should not happen.");\r
+            return null;\r
+        }else if (dnaSamples.size() == 1){\r
+            return dnaSamples.get(0);\r
+        } else{\r
+            logger.debug("there are more than one dnaSample for genetic accession number " + accessionNumberString + " this should not happen.");\r
+            return null;\r
+        }\r
+\r
+\r
+    }\r
+\r
+    /**\r
+    *\r
+    * {@inheritDoc}\r
+    */\r
+   @Override\r
+   public long countByGeneticAccessionNumber(String accessionNumberString) {\r
+       String queryString = "SELECT count(dnaSample) FROM DnaSample dnaSample JOIN dnaSample.sequences sequence WHERE sequence.geneticAccessionNumber LIKE :accessionNumberString";\r
+       Query query = getSession().createQuery(queryString);\r
+       query.setParameter("accessionNumberString", accessionNumberString);\r
+       @SuppressWarnings("unchecked")\r
+       List<DerivedUnit> dnaSamples = query.list();\r
+       long result = (long)query.uniqueResult();\r
+\r
+       return result;\r
+   }\r
+\r
+    /**\r
+     * @param dnaSamples\r
+     * @param results\r
+     */\r
+    private void extractDeterminedOriginals(List<DerivedUnit> samples, List<DerivedUnit> results) {\r
+        for (DerivedUnit sample:samples){\r
+            if (sample.getDeterminations() != null && !sample.getDeterminations().isEmpty()){\r
+                results.add(sample);\r
+            }else{\r
+                if (sample instanceof DerivedUnit){\r
+                    Set<SpecimenOrObservationBase> originals = sample.getDerivedFrom().getOriginals();\r
+                    List<DerivedUnit> originalDerivedUnits = new ArrayList();\r
+                    for (SpecimenOrObservationBase original:originals){\r
+                        if (original instanceof DerivedUnit){\r
+                            originalDerivedUnits.add((DerivedUnit)original);\r
+                        }\r
+                    }\r
+                    if(!originalDerivedUnits.isEmpty()){\r
+                        extractDeterminedOriginals(originalDerivedUnits, results);\r
+                    }\r
+                }\r
             }\r
-            query.setMaxResults(limit);\r
         }\r
+    }\r
 \r
-        List results = query.list();\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public List<SpecimenOrObservationBase> findOriginalsForDerivedUnit(UUID derivedUnitUuid, List<String> propertyPaths) {\r
+        String queryString = "SELECT DISTINCT o FROM DerivedUnit du"\r
+                + " JOIN du.derivedFrom.originals o WHERE du.uuid LIKE :derivedUnitUuid";\r
+        Query query = getSession().createQuery(queryString);\r
+        query.setParameter("derivedUnitUuid", derivedUnitUuid);\r
+        @SuppressWarnings("unchecked")\r
+        List<SpecimenOrObservationBase> results = query.list();\r
         defaultBeanInitializer.initializeAll(results, propertyPaths);\r
         return results;\r
     }\r
 \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public List<Point> findPointsForFieldUnitList(List<UUID> fieldUnitUuids) {\r
+        String queryString = "SELECT DISTINCT fu.gatheringEvent.exactLocation FROM FieldUnit fu"\r
+                + "  WHERE fu.uuid IN (:fieldUnitUuids)";\r
+        Query query = getSession().createQuery(queryString);\r
+        query.setParameterList("fieldUnitUuids", fieldUnitUuids);\r
+        @SuppressWarnings("unchecked")\r
+        List<Point> results = query.list();\r
+\r
+        return results;\r
+    }\r
+\r
 }