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
.HashSet
;
12 import java
.util
.List
;
14 import java
.util
.UUID
;
16 import org
.apache
.log4j
.Logger
;
17 import org
.hibernate
.Criteria
;
18 import org
.hibernate
.Hibernate
;
19 import org
.hibernate
.Query
;
20 import org
.hibernate
.Session
;
21 import org
.hibernate
.criterion
.Projections
;
22 import org
.hibernate
.criterion
.Restrictions
;
23 import org
.hibernate
.envers
.query
.AuditEntity
;
24 import org
.hibernate
.envers
.query
.AuditQuery
;
25 import org
.hibernate
.search
.FullTextSession
;
26 import org
.hibernate
.search
.Search
;
27 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
28 import org
.springframework
.stereotype
.Repository
;
30 import eu
.etaxonomy
.cdm
.model
.common
.UuidAndTitleCache
;
31 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
32 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
33 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
34 import eu
.etaxonomy
.cdm
.model
.molecular
.DnaSample
;
35 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
36 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
37 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivationEvent
;
38 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
39 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
40 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
41 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
43 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
44 import eu
.etaxonomy
.cdm
.model
.view
.AuditEvent
;
45 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IDescriptionDao
;
46 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
.IdentifiableDaoBase
;
47 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.taxon
.TaxonDaoHibernateImpl
;
48 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.IHomotypicalGroupDao
;
49 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.ITaxonNameDao
;
50 import eu
.etaxonomy
.cdm
.persistence
.dao
.occurrence
.IOccurrenceDao
;
51 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
54 * @author a.babadshanjan
58 public class OccurrenceDaoHibernateImpl
extends IdentifiableDaoBase
<SpecimenOrObservationBase
> implements IOccurrenceDao
{
60 @SuppressWarnings("unused")
61 private static final Logger logger
= Logger
.getLogger(TaxonDaoHibernateImpl
.class);
64 private IDescriptionDao descriptionDao
;
67 private ITaxonNameDao taxonNameDao
;
70 private IHomotypicalGroupDao homotypicalGroupDao
;
72 public OccurrenceDaoHibernateImpl() {
73 super(SpecimenOrObservationBase
.class);
74 indexedClasses
= new Class
[7];
75 indexedClasses
[0] = FieldUnit
.class;
76 indexedClasses
[1] = DerivedUnit
.class;
77 indexedClasses
[5] = DnaSample
.class;
81 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#countDerivationEvents(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase)
84 public int countDerivationEvents(SpecimenOrObservationBase occurence
) {
85 checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");
86 Query query
= getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
87 query
.setParameter("occurence", occurence
);
89 return ((Long
)query
.uniqueResult()).intValue();
93 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#countDeterminations(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, eu.etaxonomy.cdm.model.taxon.TaxonBase)
96 public int countDeterminations(SpecimenOrObservationBase occurrence
, TaxonBase taxonBase
) {
97 AuditEvent auditEvent
= getAuditEventFromContext();
98 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
99 Criteria criteria
= getSession().createCriteria(DeterminationEvent
.class);
100 if(occurrence
!= null) {
101 criteria
.add(Restrictions
.eq("identifiedUnit",occurrence
));
104 if(taxonBase
!= null) {
105 criteria
.add(Restrictions
.eq("taxon",taxonBase
));
108 criteria
.setProjection(Projections
.rowCount());
109 return ((Number
)criteria
.uniqueResult()).intValue();
111 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent
.class,auditEvent
.getRevisionNumber());
113 if(occurrence
!= null) {
114 query
.add(AuditEntity
.relatedId("identifiedUnit").eq(occurrence
.getId()));
117 if(taxonBase
!= null) {
118 query
.add(AuditEntity
.relatedId("taxon").eq(taxonBase
.getId()));
120 query
.addProjection(AuditEntity
.id().count("id"));
122 return ((Long
)query
.getSingleResult()).intValue();
127 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#countMedia(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase)
130 public int countMedia(SpecimenOrObservationBase occurence
) {
131 checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");
132 Query query
= getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
133 query
.setParameter("occurence", occurence
);
135 return ((Long
)query
.uniqueResult()).intValue();
139 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#getDerivationEvents(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, java.lang.Integer, java.lang.Integer, java.util.List)
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 if(pageSize
!= null) {
148 query
.setMaxResults(pageSize
);
149 if(pageNumber
!= null) {
150 query
.setFirstResult(pageNumber
* pageSize
);
152 query
.setFirstResult(0);
156 List
<DerivationEvent
> result
= query
.list();
157 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
162 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#getDeterminations(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, eu.etaxonomy.cdm.model.taxon.TaxonBase, java.lang.Integer, java.lang.Integer, java.util.List)
165 public List
<DeterminationEvent
> getDeterminations(SpecimenOrObservationBase occurrence
, TaxonBase taxonBase
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
166 AuditEvent auditEvent
= getAuditEventFromContext();
167 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
168 Criteria criteria
= getSession().createCriteria(DeterminationEvent
.class);
169 if(occurrence
!= null) {
170 criteria
.add(Restrictions
.eq("identifiedUnit",occurrence
));
173 if(taxonBase
!= null) {
174 criteria
.add(Restrictions
.eq("taxon",taxonBase
));
177 if(pageSize
!= null) {
178 criteria
.setMaxResults(pageSize
);
179 if(pageNumber
!= null) {
180 criteria
.setFirstResult(pageNumber
* pageSize
);
182 criteria
.setFirstResult(0);
185 List
<DeterminationEvent
> result
= criteria
.list();
186 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
189 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent
.class,auditEvent
.getRevisionNumber());
190 if(occurrence
!= null) {
191 query
.add(AuditEntity
.relatedId("identifiedUnit").eq(occurrence
.getId()));
194 if(taxonBase
!= null) {
195 query
.add(AuditEntity
.relatedId("taxon").eq(taxonBase
.getId()));
197 if(pageSize
!= null) {
198 query
.setMaxResults(pageSize
);
199 if(pageNumber
!= null) {
200 query
.setFirstResult(pageNumber
* pageSize
);
202 query
.setFirstResult(0);
205 List
<DeterminationEvent
> result
= query
.getResultList();
206 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
212 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#getMedia(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, java.lang.Integer, java.lang.Integer, java.util.List)
215 public List
<Media
> getMedia(SpecimenOrObservationBase occurence
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
216 checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
217 Query query
= getSession().createQuery("select media from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
218 query
.setParameter("occurence", occurence
);
220 if(pageSize
!= null) {
221 query
.setMaxResults(pageSize
);
222 if(pageNumber
!= null) {
223 query
.setFirstResult(pageNumber
* pageSize
);
225 query
.setFirstResult(0);
229 List
<Media
> results
= query
.list();
230 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
235 * @see eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase#rebuildIndex()
238 public void rebuildIndex() {
239 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
241 for(SpecimenOrObservationBase occurrence
: list(null,null)) { // re-index all taxon base
243 for(DeterminationEvent determination
: (Set
<DeterminationEvent
>)occurrence
.getDeterminations()) {
244 Hibernate
.initialize(determination
.getActor());
245 Hibernate
.initialize(determination
.getTaxon());
247 Hibernate
.initialize(occurrence
.getDefinition());
248 if(occurrence
instanceof DerivedUnit
) {
249 DerivedUnit derivedUnit
= (DerivedUnit
) occurrence
;
250 Hibernate
.initialize(derivedUnit
.getCollection());
251 if(derivedUnit
.getCollection() != null) {
252 Hibernate
.initialize(derivedUnit
.getCollection().getSuperCollection());
253 Hibernate
.initialize(derivedUnit
.getCollection().getInstitute());
255 Hibernate
.initialize(derivedUnit
.getStoredUnder());
256 SpecimenOrObservationBase original
= derivedUnit
.getOriginalUnit();
257 if(original
!= null && original
.isInstanceOf(FieldUnit
.class)) {
258 FieldUnit fieldUnit
= original
.deproxy(original
, FieldUnit
.class);
259 Hibernate
.initialize(fieldUnit
.getGatheringEvent());
260 if(fieldUnit
.getGatheringEvent() != null) {
261 Hibernate
.initialize(fieldUnit
.getGatheringEvent().getActor());
265 fullTextSession
.index(occurrence
);
267 fullTextSession
.flushToIndexes();
271 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#count(java.lang.Class, eu.etaxonomy.cdm.model.taxon.TaxonBase)
274 public int count(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonBase determinedAs
) {
276 Criteria criteria
= null;
278 criteria
= getSession().createCriteria(type
);
280 criteria
= getSession().createCriteria(clazz
);
283 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxon", determinedAs
));
284 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
285 return ((Number
)criteria
.uniqueResult()).intValue();
289 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#list(java.lang.Class, eu.etaxonomy.cdm.model.taxon.TaxonBase, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
292 public List
<SpecimenOrObservationBase
> list(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonBase determinedAs
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
293 Criteria criteria
= null;
295 criteria
= getSession().createCriteria(type
);
297 criteria
= getSession().createCriteria(clazz
);
300 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxon", determinedAs
));
304 criteria
.setFirstResult(start
);
306 criteria
.setFirstResult(0);
308 criteria
.setMaxResults(limit
);
311 addOrder(criteria
,orderHints
);
313 List
<SpecimenOrObservationBase
> results
= criteria
.list();
314 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
319 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#getDerivedUnitUuidAndTitleCache()
322 public List
<UuidAndTitleCache
<DerivedUnit
>> getDerivedUnitUuidAndTitleCache() {
323 List
<UuidAndTitleCache
<DerivedUnit
>> list
= new ArrayList
<UuidAndTitleCache
<DerivedUnit
>>();
324 Session session
= getSession();
326 Query query
= session
.createQuery("select uuid, titleCache from " + type
.getSimpleName() + " where NOT dtype = " + FieldUnit
.class.getSimpleName());
328 List
<Object
[]> result
= query
.list();
330 for(Object
[] object
: result
){
331 list
.add(new UuidAndTitleCache
<DerivedUnit
>(DerivedUnit
.class, (UUID
) object
[0], (String
) object
[1]));
338 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#getFieldUnitUuidAndTitleCache()
341 public List
<UuidAndTitleCache
<FieldUnit
>> getFieldUnitUuidAndTitleCache() {
342 List
<UuidAndTitleCache
<FieldUnit
>> list
= new ArrayList
<UuidAndTitleCache
<FieldUnit
>>();
343 Session session
= getSession();
345 Query query
= session
.createQuery("select uuid, titleCache from " + type
.getSimpleName() + " where dtype = " + FieldUnit
.class.getSimpleName());
347 List
<Object
[]> result
= query
.list();
349 for(Object
[] object
: result
){
350 list
.add(new UuidAndTitleCache
<FieldUnit
>(FieldUnit
.class, (UUID
) object
[0], (String
) object
[1]));
357 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#listByAnyAssociation(java.lang.Class, eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
360 public <T
extends SpecimenOrObservationBase
> List
<T
> listByAssociatedTaxon(Class
<T
> type
,
361 Taxon associatedTaxon
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
363 Set
<SpecimenOrObservationBase
> setOfAll
= new HashSet
<SpecimenOrObservationBase
>();
365 // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
366 List
<SpecimenOrObservationBase
> byDetermination
= list(type
, associatedTaxon
, null, 0, null, null);
367 setOfAll
.addAll(byDetermination
);
369 // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits
370 List
<IndividualsAssociation
> byIndividualsAssociation
= descriptionDao
.getDescriptionElementForTaxon(
371 associatedTaxon
.getUuid(), null, IndividualsAssociation
.class, null, 0, null);
372 for(IndividualsAssociation individualsAssociation
: byIndividualsAssociation
){
373 setOfAll
.add(individualsAssociation
.getAssociatedSpecimenOrObservation());
376 // SpecimenTypeDesignations may be associated with the TaxonName.
377 List
<SpecimenTypeDesignation
> bySpecimenTypeDesignation
= taxonNameDao
.getTypeDesignations(associatedTaxon
.getName(),
378 SpecimenTypeDesignation
.class, null, null, 0, null);
379 for (SpecimenTypeDesignation specimenTypeDesignation
: bySpecimenTypeDesignation
) {
380 setOfAll
.add(specimenTypeDesignation
.getTypeSpecimen());
383 // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.
384 for(HomotypicalGroup homotypicalGroup
: associatedTaxon
.getHomotypicSynonymyGroups()) {
385 List
<SpecimenTypeDesignation
> byHomotypicalGroup
= homotypicalGroupDao
.getTypeDesignations(homotypicalGroup
, SpecimenTypeDesignation
.class, null, null, 0, null);
386 for (SpecimenTypeDesignation specimenTypeDesignation
: byHomotypicalGroup
) {
387 setOfAll
.add(specimenTypeDesignation
.getTypeSpecimen());
391 if(setOfAll
.size() == 0){
392 // no need querying the data base
393 return new ArrayList
<T
>();
398 " from SpecimenOrObservationBase sob" +
399 " where sob in (:setOfAll)";
402 queryString
+= " and sob.class = :type";
405 if(orderHints
!= null && orderHints
.size() > 0){
406 queryString
+= " order by ";
407 String orderStr
= "";
408 for(OrderHint orderHint
: orderHints
){
409 if(orderStr
.length() > 0){
412 queryString
+= "sob." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
414 queryString
+= orderStr
;
417 Query query
= getSession().createQuery(queryString
);
418 query
.setParameterList("setOfAll", setOfAll
);
421 query
.setParameter("type", type
.getSimpleName());
426 query
.setFirstResult(start
);
428 query
.setFirstResult(0);
430 query
.setMaxResults(limit
);
434 List
<T
> results
= query
.list();
435 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
440 public Collection
<SpecimenTypeDesignation
> listTypeDesignations(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
441 String queryString
= "FROM SpecimenTypeDesignation designations WHERE designations.typeSpecimen = :specimen";
443 if(orderHints
!= null && orderHints
.size() > 0){
444 queryString
+= " order by ";
445 String orderStr
= "";
446 for(OrderHint orderHint
: orderHints
){
447 if(orderStr
.length() > 0){
450 queryString
+= "designations." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
452 queryString
+= orderStr
;
455 Query query
= getSession().createQuery(queryString
);
456 query
.setParameter("specimen", specimen
);
460 query
.setFirstResult(start
);
462 query
.setFirstResult(0);
464 query
.setMaxResults(limit
);
467 List results
= query
.list();
468 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
473 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#listAssociatedTaxa(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase)
476 public Collection
<IndividualsAssociation
> listIndividualsAssociations(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
477 //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
478 String queryString
= "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";
480 if(orderHints
!= null && orderHints
.size() > 0){
481 queryString
+= " order by ";
482 String orderStr
= "";
483 for(OrderHint orderHint
: orderHints
){
484 if(orderStr
.length() > 0){
487 queryString
+= "associations." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
489 queryString
+= orderStr
;
492 Query query
= getSession().createQuery(queryString
);
493 query
.setParameter("specimen", specimen
);
497 query
.setFirstResult(start
);
499 query
.setFirstResult(0);
501 query
.setMaxResults(limit
);
504 List results
= query
.list();
505 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
510 * @see eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao#listAssociatedTaxa(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase)
513 public Collection
<DescriptionBase
<?
>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
514 //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
515 String queryString
= "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";
517 if(orderHints
!= null && orderHints
.size() > 0){
518 queryString
+= " order by ";
519 String orderStr
= "";
520 for(OrderHint orderHint
: orderHints
){
521 if(orderStr
.length() > 0){
524 queryString
+= "descriptions." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
526 queryString
+= orderStr
;
529 Query query
= getSession().createQuery(queryString
);
530 query
.setParameter("specimen", specimen
);
534 query
.setFirstResult(start
);
536 query
.setFirstResult(0);
538 query
.setMaxResults(limit
);
541 List results
= query
.list();
542 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);