2 * Copyright (C) 2008 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
7 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.occurrence
;
9 import java
.util
.ArrayList
;
10 import java
.util
.Collection
;
11 import java
.util
.Collections
;
12 import java
.util
.HashSet
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
17 import org
.apache
.log4j
.Logger
;
18 import org
.hibernate
.Criteria
;
19 import org
.hibernate
.Hibernate
;
20 import org
.hibernate
.Query
;
21 import org
.hibernate
.Session
;
22 import org
.hibernate
.criterion
.Disjunction
;
23 import org
.hibernate
.criterion
.ProjectionList
;
24 import org
.hibernate
.criterion
.Projections
;
25 import org
.hibernate
.criterion
.Restrictions
;
26 import org
.hibernate
.envers
.query
.AuditEntity
;
27 import org
.hibernate
.envers
.query
.AuditQuery
;
28 import org
.hibernate
.search
.FullTextSession
;
29 import org
.hibernate
.search
.Search
;
30 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
31 import org
.springframework
.stereotype
.Repository
;
33 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
34 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
35 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
36 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
37 import eu
.etaxonomy
.cdm
.model
.molecular
.DnaSample
;
38 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
39 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
40 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
41 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivationEvent
;
42 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
43 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
44 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
45 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
46 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationType
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
51 import eu
.etaxonomy
.cdm
.model
.view
.AuditEvent
;
52 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IDescriptionDao
;
53 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
.IdentifiableDaoBase
;
54 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.taxon
.TaxonDaoHibernateImpl
;
55 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.IHomotypicalGroupDao
;
56 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.ITaxonNameDao
;
57 import eu
.etaxonomy
.cdm
.persistence
.dao
.occurrence
.IOccurrenceDao
;
58 import eu
.etaxonomy
.cdm
.persistence
.dto
.SpecimenNodeWrapper
;
59 import eu
.etaxonomy
.cdm
.persistence
.dto
.UuidAndTitleCache
;
60 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
61 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
64 * @author a.babadshanjan
68 public class OccurrenceDaoHibernateImpl
69 extends IdentifiableDaoBase
<SpecimenOrObservationBase
>
70 implements IOccurrenceDao
{
72 @SuppressWarnings("unused")
73 private static final Logger logger
= Logger
.getLogger(TaxonDaoHibernateImpl
.class);
76 private IDescriptionDao descriptionDao
;
79 private ITaxonNameDao taxonNameDao
;
82 private IHomotypicalGroupDao homotypicalGroupDao
;
84 public OccurrenceDaoHibernateImpl() {
85 super(SpecimenOrObservationBase
.class);
86 indexedClasses
= new Class
[7];
87 indexedClasses
[0] = FieldUnit
.class;
88 indexedClasses
[1] = DerivedUnit
.class;
89 indexedClasses
[5] = DnaSample
.class;
93 public long countDerivationEvents(SpecimenOrObservationBase occurence
) {
94 checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");
95 Query query
= getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
96 query
.setParameter("occurence", occurence
);
98 return (Long
)query
.uniqueResult();
102 public long countDeterminations(SpecimenOrObservationBase occurrence
, TaxonBase taxonBase
) {
103 AuditEvent auditEvent
= getAuditEventFromContext();
104 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
105 Criteria criteria
= getCriteria(DeterminationEvent
.class);
106 if(occurrence
!= null) {
107 criteria
.add(Restrictions
.eq("identifiedUnit",occurrence
));
110 if(taxonBase
!= null) {
111 criteria
.add(Restrictions
.eq("taxon",taxonBase
));
114 criteria
.setProjection(Projections
.rowCount());
115 return (Long
)criteria
.uniqueResult();
117 AuditQuery query
= makeAuditQuery(DeterminationEvent
.class,auditEvent
);
119 if(occurrence
!= null) {
120 query
.add(AuditEntity
.relatedId("identifiedUnit").eq(occurrence
.getId()));
123 if(taxonBase
!= null) {
124 query
.add(AuditEntity
.relatedId("taxon").eq(taxonBase
.getId()));
126 query
.addProjection(AuditEntity
.id().count());
128 return (Long
)query
.getSingleResult();
133 public long countMedia(SpecimenOrObservationBase occurence
) {
134 checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");
135 Query query
= getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
136 query
.setParameter("occurence", occurence
);
138 return (Long
)query
.uniqueResult();
142 public List
<DerivationEvent
> getDerivationEvents(SpecimenOrObservationBase occurence
, Integer pageSize
,Integer pageNumber
, List
<String
> propertyPaths
) {
143 checkNotInPriorView("OccurrenceDaoHibernateImpl.getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber)");
144 Query query
= getSession().createQuery("select distinct derivationEvent from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
145 query
.setParameter("occurence", occurence
);
147 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
149 @SuppressWarnings("unchecked")
150 List
<DerivationEvent
> result
= query
.list();
151 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
156 public List
<DeterminationEvent
> getDeterminations(SpecimenOrObservationBase occurrence
, TaxonBase taxonBase
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
157 AuditEvent auditEvent
= getAuditEventFromContext();
158 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
159 Criteria criteria
= getSession().createCriteria(DeterminationEvent
.class);
160 if(occurrence
!= null) {
161 criteria
.add(Restrictions
.eq("identifiedUnit",occurrence
));
164 if(taxonBase
!= null) {
165 criteria
.add(Restrictions
.eq("taxon",taxonBase
));
168 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
170 @SuppressWarnings("unchecked")
171 List
<DeterminationEvent
> result
= criteria
.list();
172 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
175 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent
.class,auditEvent
.getRevisionNumber());
176 if(occurrence
!= null) {
177 query
.add(AuditEntity
.relatedId("identifiedUnit").eq(occurrence
.getId()));
180 if(taxonBase
!= null) {
181 query
.add(AuditEntity
.relatedId("taxon").eq(taxonBase
.getId()));
183 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
185 @SuppressWarnings("unchecked")
186 List
<DeterminationEvent
> result
= query
.getResultList();
187 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
193 public List
<Media
> getMedia(SpecimenOrObservationBase occurence
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
194 checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
195 Query query
= getSession().createQuery(
197 + " FROM SpecimenOrObservationBase occurence "
198 + " JOIN occurence.media media "
199 + " WHERE occurence = :occurence");
200 query
.setParameter("occurence", occurence
);
202 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
204 @SuppressWarnings("unchecked")
205 List
<Media
> results
= query
.list();
206 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
211 public void rebuildIndex() {
212 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
214 for(SpecimenOrObservationBase
<?
> occurrence
: list(null,null)) { // re-index all taxon base
216 for(DeterminationEvent determination
: occurrence
.getDeterminations()) {
217 Hibernate
.initialize(determination
.getActor());
218 Hibernate
.initialize(determination
.getTaxon());
220 Hibernate
.initialize(occurrence
.getDefinition());
221 if(occurrence
instanceof DerivedUnit
) {
222 DerivedUnit derivedUnit
= (DerivedUnit
) occurrence
;
223 Hibernate
.initialize(derivedUnit
.getCollection());
224 if(derivedUnit
.getCollection() != null) {
225 Hibernate
.initialize(derivedUnit
.getCollection().getSuperCollection());
226 Hibernate
.initialize(derivedUnit
.getCollection().getInstitute());
228 Hibernate
.initialize(derivedUnit
.getStoredUnder());
229 SpecimenOrObservationBase
<?
> original
= derivedUnit
.getOriginalUnit();
230 if(original
!= null && original
.isInstanceOf(FieldUnit
.class)) {
231 FieldUnit fieldUnit
= CdmBase
.deproxy(original
, FieldUnit
.class);
232 Hibernate
.initialize(fieldUnit
.getGatheringEvent());
233 if(fieldUnit
.getGatheringEvent() != null) {
234 Hibernate
.initialize(fieldUnit
.getGatheringEvent().getActor());
238 fullTextSession
.index(occurrence
);
240 fullTextSession
.flushToIndexes();
244 public long count(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonName determinedAs
) {
246 Criteria criteria
= getCriteria(clazz
);
248 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxonName", determinedAs
));
249 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
250 return (Long
)criteria
.uniqueResult();
254 public List
<SpecimenOrObservationBase
> list(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonName determinedAs
,
255 Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
256 Criteria criteria
= getCriteria(clazz
);
258 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxonName", determinedAs
));
260 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
261 addOrder(criteria
,orderHints
);
263 @SuppressWarnings({ "unchecked", "rawtypes" })
264 List
<SpecimenOrObservationBase
> results
= criteria
.list();
265 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
270 public long count(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonBase determinedAs
) {
272 Criteria criteria
= getCriteria(clazz
);
274 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxon", determinedAs
));
275 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
276 return (Long
)criteria
.uniqueResult();
281 public List
<SpecimenOrObservationBase
> list(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonBase determinedAs
,
282 Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
284 Criteria criteria
= getCriteria(clazz
);
286 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxon", determinedAs
));
288 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
289 addOrder(criteria
,orderHints
);
291 @SuppressWarnings({ "unchecked", "rawtypes" })
292 List
<SpecimenOrObservationBase
> results
= criteria
.list();
293 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
298 public <T
extends SpecimenOrObservationBase
> List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> findOccurrencesUuidAndTitleCache(
299 Class
<T
> clazz
, String queryString
, String significantIdentifier
, SpecimenOrObservationType recordBasis
,
300 Taxon associatedTaxon
, TaxonName associatedTaxonName
, MatchMode matchmode
, Integer limit
, Integer start
,
301 List
<OrderHint
> orderHints
) {
302 Criteria criteria
= createFindOccurrenceCriteria(clazz
, queryString
, significantIdentifier
, recordBasis
,
303 associatedTaxon
, associatedTaxonName
, matchmode
, limit
, start
, orderHints
, null);
305 ProjectionList projectionList
= Projections
.projectionList();
306 projectionList
.add(Projections
.property("uuid"));
307 projectionList
.add(Projections
.property("id"));
308 projectionList
.add(Projections
.property("titleCache"));
309 criteria
.setProjection(projectionList
);
311 @SuppressWarnings("unchecked")
312 List
<Object
[]> result
= criteria
.list();
313 List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> uuidAndTitleCacheList
= new ArrayList
<>();
314 for(Object
[] object
: result
){
315 uuidAndTitleCacheList
.add(new UuidAndTitleCache
<>((UUID
) object
[0],(Integer
) object
[1], (String
) object
[2]));
317 return uuidAndTitleCacheList
;
319 return Collections
.emptyList();
324 public <T
extends SpecimenOrObservationBase
> List
<T
> findOccurrences(Class
<T
> clazz
, String queryString
,
325 String significantIdentifier
, SpecimenOrObservationType recordBasis
, Taxon associatedTaxon
, TaxonName associatedTaxonName
,
326 MatchMode matchmode
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
328 Criteria criteria
= createFindOccurrenceCriteria(clazz
, queryString
, significantIdentifier
, recordBasis
,
329 associatedTaxon
, associatedTaxonName
, matchmode
, limit
, start
, orderHints
, propertyPaths
);
331 @SuppressWarnings("unchecked")
332 List
<T
> results
= criteria
.list();
333 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
336 return Collections
.emptyList();
340 private <T
extends SpecimenOrObservationBase
> Criteria
createFindOccurrenceCriteria(Class
<T
> clazz
, String queryString
,
341 String significantIdentifier
, SpecimenOrObservationType recordBasis
, Taxon associatedTaxon
, TaxonName associatedTaxonName
, MatchMode matchmode
, Integer limit
,
342 Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
343 Criteria criteria
= null;
346 criteria
= getSession().createCriteria(type
);
348 criteria
= getSession().createCriteria(clazz
);
352 if (queryString
!= null) {
353 if(matchmode
== null) {
354 matchmode
= MatchMode
.ANYWHERE
;
355 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
)));
356 } else if(matchmode
== MatchMode
.BEGINNING
) {
357 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.START
));
358 } else if(matchmode
== MatchMode
.END
) {
359 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.END
));
360 } else if(matchmode
== MatchMode
.EXACT
) {
361 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.EXACT
));
363 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.ANYWHERE
));
367 //significant identifier
368 if (significantIdentifier
!= null) {
369 criteria
.add(Restrictions
.or(Restrictions
.ilike("accessionNumber", significantIdentifier
),
370 Restrictions
.ilike("catalogNumber", significantIdentifier
), Restrictions
.ilike("barcode", significantIdentifier
)));
373 //recordBasis/SpecimenOrObservationType
374 Set
<SpecimenOrObservationType
> typeAndSubtypes
= new HashSet
<SpecimenOrObservationType
>();
375 if(recordBasis
==null){
377 SpecimenOrObservationType
[] values
= SpecimenOrObservationType
.values();
378 for (SpecimenOrObservationType specimenOrObservationType
: values
) {
379 typeAndSubtypes
.add(specimenOrObservationType
);
383 typeAndSubtypes
= recordBasis
.getGeneralizationOf(true);
384 typeAndSubtypes
.add(recordBasis
);
386 criteria
.add(Restrictions
.in("recordBasis", typeAndSubtypes
));
388 Set
<UUID
> associationUuids
= new HashSet
<UUID
>();
390 if(associatedTaxon
!=null){
391 List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> associatedTaxaList
= listUuidAndTitleCacheByAssociatedTaxon(clazz
, associatedTaxon
, limit
, start
, orderHints
);
392 if(associatedTaxaList
!=null){
393 for (UuidAndTitleCache
<SpecimenOrObservationBase
> uuidAndTitleCache
: associatedTaxaList
) {
394 associationUuids
.add(uuidAndTitleCache
.getUuid());
398 //taxon name associations
399 else if(associatedTaxonName
!=null){
400 List
<?
extends SpecimenOrObservationBase
> associatedTaxaList
= listByAssociatedTaxonName(clazz
, associatedTaxonName
, limit
, start
, orderHints
, propertyPaths
);
401 if(associatedTaxaList
!=null){
402 for (SpecimenOrObservationBase
<?
> specimenOrObservationBase
: associatedTaxaList
) {
403 associationUuids
.add(specimenOrObservationBase
.getUuid());
407 if(associatedTaxon
!=null || associatedTaxonName
!=null){
408 if(!associationUuids
.isEmpty()){
409 criteria
.add(Restrictions
.in("uuid", associationUuids
));
417 criteria
.setFirstResult(start
);
419 criteria
.setFirstResult(0);
421 criteria
.setMaxResults(limit
);
424 if(orderHints
!=null){
425 addOrder(criteria
,orderHints
);
432 public <T
extends SpecimenOrObservationBase
> long countOccurrences(Class
<T
> clazz
, String queryString
,
433 String significantIdentifier
, SpecimenOrObservationType recordBasis
, Taxon associatedTaxon
, TaxonName associatedTaxonName
,
434 MatchMode matchmode
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
436 Criteria criteria
= createFindOccurrenceCriteria(clazz
, queryString
, significantIdentifier
, recordBasis
,
437 associatedTaxon
, associatedTaxonName
, matchmode
, limit
, start
, orderHints
, propertyPaths
);
440 criteria
.setProjection(Projections
.rowCount());
441 return (Long
)criteria
.uniqueResult();
448 public List
<UuidAndTitleCache
<DerivedUnit
>> getDerivedUnitUuidAndTitleCache(Integer limit
, String pattern
) {
449 List
<UuidAndTitleCache
<DerivedUnit
>> list
= new ArrayList
<>();
450 Session session
= getSession();
451 String hql
= "SELECT uuid, id, titleCache "
452 + " FROM " + type
.getSimpleName()
453 + " WHERE NOT dtype = " + FieldUnit
.class.getSimpleName();
455 if (pattern
!= null){
456 pattern
= pattern
.replace("*", "%");
457 pattern
= pattern
.replace("?", "_");
458 pattern
= pattern
+ "%";
459 query
= session
.createQuery(hql
+" AND titleCache like :pattern");
460 query
.setParameter("pattern", pattern
);
462 query
= session
.createQuery(hql
);
465 query
.setMaxResults(limit
);
468 @SuppressWarnings("unchecked")
469 List
<Object
[]> result
= query
.list();
471 for(Object
[] object
: result
){
472 list
.add(new UuidAndTitleCache
<DerivedUnit
>(DerivedUnit
.class, (UUID
) object
[0], (Integer
)object
[1], (String
) object
[2]));
479 public List
<UuidAndTitleCache
<FieldUnit
>> getFieldUnitUuidAndTitleCache() {
480 List
<UuidAndTitleCache
<FieldUnit
>> list
= new ArrayList
<>();
481 Session session
= getSession();
483 Query query
= session
.createQuery("select uuid, id, titleCache from " + type
.getSimpleName() + " where dtype = " + FieldUnit
.class.getSimpleName());
485 @SuppressWarnings("unchecked")
486 List
<Object
[]> result
= query
.list();
488 for(Object
[] object
: result
){
489 list
.add(new UuidAndTitleCache
<FieldUnit
>(FieldUnit
.class, (UUID
) object
[0], (Integer
)object
[1], (String
) object
[2]));
496 public <T
extends SpecimenOrObservationBase
> List
<T
> listByAssociatedTaxonName(Class
<T
> type
,
497 TaxonName associatedTaxonName
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
499 @SuppressWarnings("rawtypes")
500 Set
<SpecimenOrObservationBase
> setOfAll
= new HashSet
<>();
502 // A Taxon name may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
503 @SuppressWarnings("rawtypes")
504 List
<SpecimenOrObservationBase
> byDetermination
= list(type
, associatedTaxonName
, null, 0, null, null);
505 setOfAll
.addAll(byDetermination
);
507 if(setOfAll
.size() == 0){
508 // no need querying the data base
509 return new ArrayList
<T
>();
514 " FROM SpecimenOrObservationBase sob" +
515 " WHERE sob in (:setOfAll)";
517 if(type
!= null && !type
.equals(SpecimenOrObservationBase
.class)){
518 queryString
+= " AND sob.class = :type";
520 queryString
+= orderByClause("sob", orderHints
);
522 Query query
= getSession().createQuery(queryString
);
523 query
.setParameterList("setOfAll", setOfAll
);
525 if(type
!= null && !type
.equals(SpecimenOrObservationBase
.class)){
526 query
.setParameter("type", type
.getSimpleName());
529 addLimitAndStart(query
, limit
, start
);
531 @SuppressWarnings("unchecked")
532 List
<T
> results
= query
.list();
533 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
537 private List
<SpecimenNodeWrapper
> querySpecimen(
538 Query query
, List
<UUID
> taxonNodeUuids
,
539 Integer limit
, Integer start
){
540 query
.setParameterList("taxonNodeUuids", taxonNodeUuids
);
542 addLimitAndStart(query
, limit
, start
);
544 List
<SpecimenNodeWrapper
> list
= new ArrayList
<>();
545 @SuppressWarnings("unchecked")
546 List
<Object
[]> result
= query
.list();
547 for(Object
[] object
: result
){
548 list
.add(new SpecimenNodeWrapper(
549 new UuidAndTitleCache
<>(
553 (TaxonNode
)object
[3]));
558 private List
<SpecimenNodeWrapper
> queryIndividualAssociatedSpecimen(List
<UUID
> taxonNodeUuids
,
559 Integer limit
, Integer start
){
560 String queryString
= "SELECT "
561 + "de.associatedSpecimenOrObservation.uuid, "
562 + "de.associatedSpecimenOrObservation.id, "
563 + "de.associatedSpecimenOrObservation.titleCache, "
565 + "FROM DescriptionElementBase AS de "
566 + "LEFT JOIN de.inDescription AS d "
567 + "LEFT JOIN d.taxon AS t "
568 + "JOIN t.taxonNodes AS tn "
569 + "WHERE d.class = 'TaxonDescription' "
570 + "AND tn.uuid in (:taxonNodeUuids) "
572 Query query
= getSession().createQuery(queryString
);
573 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
576 private List
<SpecimenNodeWrapper
> queryTypeSpecimen(List
<UUID
> taxonNodeUuids
,
577 Integer limit
, Integer start
){
578 String queryString
= "SELECT "
579 + "td.typeSpecimen.uuid, "
580 + "td.typeSpecimen.id, "
581 + "td.typeSpecimen.titleCache, "
583 + "FROM SpecimenTypeDesignation AS td "
584 + "LEFT JOIN td.typifiedNames AS tn "
585 + "LEFT JOIN tn.taxonBases AS t "
586 + "JOIN t.taxonNodes AS tn "
587 + "WHERE tn.uuid in (:taxonNodeUuids) "
589 Query query
= getSession().createQuery(queryString
);
590 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
593 private List
<SpecimenNodeWrapper
> queryTaxonDeterminations(List
<UUID
> taxonNodeUuids
,
594 Integer limit
, Integer start
){
595 String queryString
= "SELECT "
596 + "det.identifiedUnit.uuid, "
597 + "det.identifiedUnit.id, "
598 + "det.identifiedUnit.titleCache, "
600 + "FROM DeterminationEvent AS det "
601 + "LEFT JOIN det.taxon AS t "
602 + "JOIN t.taxonNodes AS tn "
603 + "WHERE tn.uuid in (:taxonNodeUuids) "
605 Query query
= getSession().createQuery(queryString
);
606 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
609 private List
<SpecimenNodeWrapper
> queryTaxonNameDeterminations(List
<UUID
> taxonNodeUuids
,
610 Integer limit
, Integer start
){
611 String queryString
= "SELECT "
612 + "det.identifiedUnit.uuid, "
613 + "det.identifiedUnit.id, "
614 + "det.identifiedUnit.titleCache, "
616 + "FROM DeterminationEvent AS det "
617 + "LEFT JOIN det.taxonName AS n "
618 + "LEFT JOIN n.taxonBases AS t "
619 + "JOIN t.taxonNodes AS tn "
620 + "WHERE tn.uuid in (:taxonNodeUuids) "
622 Query query
= getSession().createQuery(queryString
);
623 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
627 public Collection
<SpecimenNodeWrapper
> listUuidAndTitleCacheByAssociatedTaxon(List
<UUID
> taxonNodeUuids
,
628 Integer limit
, Integer start
){
630 Collection
<SpecimenNodeWrapper
> wrappers
= new HashSet
<>();
631 wrappers
.addAll(queryIndividualAssociatedSpecimen(taxonNodeUuids
, limit
, start
));
632 wrappers
.addAll(queryTaxonDeterminations(taxonNodeUuids
, limit
, start
));
633 wrappers
.addAll(queryTaxonNameDeterminations(taxonNodeUuids
, limit
, start
));
634 wrappers
.addAll(queryTypeSpecimen(taxonNodeUuids
, limit
, start
));
640 public <T
extends SpecimenOrObservationBase
> List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> listUuidAndTitleCacheByAssociatedTaxon(Class
<T
> clazz
, Taxon associatedTaxon
,
641 Integer limit
, Integer start
, List
<OrderHint
> orderHints
){
642 Query query
= createSpecimenQuery("sob.uuid, sob.id, sob.titleCache", clazz
, associatedTaxon
, limit
, start
, orderHints
, null);
644 return Collections
.emptyList();
646 List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> list
= new ArrayList
<>();
647 @SuppressWarnings("unchecked")
648 List
<Object
[]> result
= query
.list();
649 for(Object
[] object
: result
){
650 list
.add(new UuidAndTitleCache
<>((UUID
) object
[0],(Integer
) object
[1], (String
) object
[2]));
656 public <T
extends SpecimenOrObservationBase
> List
<T
> listByAssociatedTaxon(Class
<T
> clazz
,
657 Taxon associatedTaxon
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
658 Query query
= createSpecimenQuery("sob", clazz
, associatedTaxon
, limit
, start
, orderHints
, propertyPaths
);
660 return Collections
.emptyList();
662 @SuppressWarnings("unchecked")
663 List
<T
> results
= query
.list();
664 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
668 private <T
extends SpecimenOrObservationBase
> Query
createSpecimenQuery(String select
, Class
<T
> clazz
,
669 Taxon associatedTaxon
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
670 Set
<SpecimenOrObservationBase
> setOfAll
= new HashSet
<>();
671 Set
<Integer
> setOfAllIds
= new HashSet
<>();
673 Criteria criteria
= null;
675 criteria
= getSession().createCriteria(type
, "specimen");
677 criteria
= getSession().createCriteria(clazz
, "specimen");
680 Disjunction determinationOr
= Restrictions
.disjunction();
682 // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
683 Criteria determinationsCriteria
= criteria
.createCriteria("determinations");
685 determinationOr
.add(Restrictions
.eq("taxon", associatedTaxon
));
686 //check also for synonyms
687 for (Synonym synonym
: associatedTaxon
.getSynonyms()) {
688 determinationOr
.add(Restrictions
.eq("taxon", synonym
));
691 //check also for name determinations
692 determinationOr
.add(Restrictions
.eq("taxonName", associatedTaxon
.getName()));
693 for (TaxonName synonymName
: associatedTaxon
.getSynonymNames()) {
694 determinationOr
.add(Restrictions
.eq("taxonName", synonymName
));
697 determinationsCriteria
.add(determinationOr
);
701 criteria
.setFirstResult(start
);
703 criteria
.setFirstResult(0);
705 criteria
.setMaxResults(limit
);
707 criteria
.setProjection(Projections
.property("id"));
709 addOrder(criteria
,orderHints
);
711 @SuppressWarnings("unchecked")
712 List
<Integer
> detResults
= criteria
.list();
713 setOfAllIds
.addAll(detResults
);
715 // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits
716 setOfAllIds
.addAll(descriptionDao
.getIndividualAssociationSpecimenIDs(
717 associatedTaxon
.getUuid(), null, null, 0, null));
720 // SpecimenTypeDesignations may be associated with the TaxonName.
721 setOfAllIds
.addAll(taxonNameDao
.getTypeSpecimenIdsForTaxonName(
722 associatedTaxon
.getName(), null, null, null));
724 // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.
725 //TODO adapt to set of ids
726 for(HomotypicalGroup homotypicalGroup
: associatedTaxon
.getHomotypicSynonymyGroups()) {
727 List
<SpecimenTypeDesignation
> byHomotypicalGroup
= homotypicalGroupDao
.getTypeDesignations(homotypicalGroup
, SpecimenTypeDesignation
.class, null, null, 0, null);
728 for (SpecimenTypeDesignation specimenTypeDesignation
: byHomotypicalGroup
) {
729 setOfAll
.add(specimenTypeDesignation
.getTypeSpecimen());
733 if(setOfAllIds
.size() == 0){
734 // no need querying the data base
740 " from SpecimenOrObservationBase sob" +
741 " where sob.id in (:setOfAllIds)";
743 if(clazz
!= null && !clazz
.equals(SpecimenOrObservationBase
.class)){
744 queryString
+= " and sob.class = :type ";
747 if(orderHints
!= null && orderHints
.size() > 0){
748 queryString
+= " order by ";
749 String orderStr
= "";
750 for(OrderHint orderHint
: orderHints
){
751 if(orderStr
.length() > 0){
754 queryString
+= "sob." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
756 queryString
+= orderStr
;
759 Query query
= getSession().createQuery(queryString
);
760 query
.setParameterList("setOfAllIds", setOfAllIds
);
762 if(clazz
!= null && !clazz
.equals(SpecimenOrObservationBase
.class)){
763 query
.setParameter("type", clazz
.getSimpleName());
766 addLimitAndStart(query
, limit
, start
);
772 public Collection
<SpecimenOrObservationBase
> listBySpecimenOrObservationType(SpecimenOrObservationType type
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
773 String queryString
= "FROM SpecimenOrObservationBase specimens "
774 + " WHERE specimens.recordBasis = :type ";
776 queryString
+= orderByClause("specimens", orderHints
);
778 Query query
= getSession().createQuery(queryString
);
779 query
.setParameter("type", type
);
781 addLimitAndStart(query
, limit
, start
);
783 @SuppressWarnings({ "unchecked", "rawtypes" })
784 List
<SpecimenOrObservationBase
> results
= query
.list();
785 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
791 public Collection
<DeterminationEvent
> listDeterminationEvents(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
792 String queryString
= "FROM DeterminationEvent determination "
793 + " WHERE determination.identifiedUnit = :specimen";
795 queryString
+= orderByClause("determination", orderHints
);
797 Query query
= getSession().createQuery(queryString
);
798 query
.setParameter("specimen", specimen
);
800 addLimitAndStart(query
, limit
, start
);
802 @SuppressWarnings("unchecked")
803 List
<DeterminationEvent
> results
= query
.list();
804 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
809 public Collection
<SpecimenTypeDesignation
> listTypeDesignations(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
810 String queryString
= "FROM SpecimenTypeDesignation designations "
811 + " WHERE designations.typeSpecimen = :specimen";
813 queryString
+= orderByClause("designations", orderHints
);
815 Query query
= getSession().createQuery(queryString
);
816 query
.setParameter("specimen", specimen
);
818 addLimitAndStart(query
, limit
, start
);
820 @SuppressWarnings("unchecked")
821 List
<SpecimenTypeDesignation
> results
= query
.list();
822 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
828 public Collection
<IndividualsAssociation
> listIndividualsAssociations(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
829 //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
830 String queryString
= "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";
832 queryString
+= orderByClause("associations", orderHints
);
834 Query query
= getSession().createQuery(queryString
);
835 query
.setParameter("specimen", specimen
);
837 addLimitAndStart(query
, limit
, start
);
839 @SuppressWarnings("unchecked")
840 List
<IndividualsAssociation
> results
= query
.list();
841 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
846 public Collection
<DescriptionBase
<?
>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
847 //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
848 String queryString
= "FROM DescriptionBase descriptions "
849 + " WHERE descriptions.describedSpecimenOrObservation = :specimen";
851 queryString
+= orderByClause("descriptions", orderHints
);
853 Query query
= getSession().createQuery(queryString
);
854 query
.setParameter("specimen", specimen
);
856 addLimitAndStart(query
, limit
, start
);
858 @SuppressWarnings("unchecked")
859 List
<DescriptionBase
<?
>> results
= query
.list();
860 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
868 public List
<FieldUnit
> getFieldUnitsForGatheringEvent(UUID gatheringEventUuid
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
869 String queryString
= "FROM SpecimenOrObservationBase sob "
870 + "WHERE sob.gatheringEvent.uuid = :gatheringEventUuid";
872 queryString
+= orderByClause("sob", orderHints
);
874 Query query
= getSession().createQuery(queryString
);
875 query
.setParameter("gatheringEventUuid", gatheringEventUuid
);
877 addLimitAndStart(query
, limit
, start
);
879 @SuppressWarnings("unchecked")
880 List
<FieldUnit
> results
= query
.list();
881 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
889 public List
<DerivedUnit
> getByGeneticAccessionNumber(String accessionNumberString
, List
<String
> propertyPaths
) {
890 String queryString
= "SELECT dnaSample FROM DnaSample dnaSample join dnaSample.sequences sequence WHERE sequence.geneticAccessionNumber LIKE :accessionNumberString";
891 Query query
= getSession().createQuery(queryString
);
892 query
.setParameter("accessionNumberString", accessionNumberString
);
893 @SuppressWarnings("unchecked")
894 List
<DerivedUnit
> results
= query
.list();
895 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);