1 // license-header java merge-point
2 //
3 // Attention: Generated code! Do not modify by hand!
4 // Generated by: hibernate/HibernateSearch.vsl in andromda-spring-cartridge.
5 //
6 package fr.ifremer.quadrige2.core.dao;
7
8 /*-
9 * #%L
10 * Quadrige2 Core :: Server API
11 * %%
12 * Copyright (C) 2017 Ifremer
13 * %%
14 * This program is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Affero General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU Affero General Public License
25 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 * #L%
27 */
28
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.HashMap;
34 import java.util.LinkedHashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import org.apache.commons.lang3.StringUtils;
39 import org.hibernate.Criteria;
40 import org.hibernate.FetchMode;
41 import org.hibernate.HibernateException;
42 import org.hibernate.Session;
43 import org.hibernate.criterion.Conjunction;
44 import org.hibernate.criterion.CriteriaSpecification;
45 import org.hibernate.criterion.Criterion;
46 import org.hibernate.criterion.Disjunction;
47 import org.hibernate.criterion.MatchMode;
48 import org.hibernate.criterion.Order;
49 import org.hibernate.criterion.Restrictions;
50 import org.hibernate.criterion.SimpleExpression;
51
52 /**
53 * Implements a generic search mechanism based on the Hibernate Criteria API. The
54 * <code>CriteriaSearch</code> allows adding parameters which function as where clause. The
55 * parameters are analyzed whether they should be considered or not. This depends both on the actual
56 * value of the parameter and on the configuration.<br>
57 * The <code>CriteriaSearch</code> is expected to be a general solution for a basic search with
58 * parameters connected by logical <b>and</b>. This search does <b>not</b> provide grouping.
59 *
60 * @author Stefan Reichert
61 * @author Peter Friese
62 * @author Chad Brandon
63 * @see Criteria
64 * @see Restrictions
65 */
66 public class CriteriaSearch
67 {
68 private CriteriaSearchConfiguration configuration;
69 private Criteria rootCriteria;
70 private Map<String, Criteria> childCriteriaMap;
71 private List<CriteriaSearchParameter> orderList;
72 private Class resultType;
73
74 private static final class ParameterComparator
75 implements Comparator
76 {
77 public int compare(final Object object1, final Object object2)
78 {
79 final CriteriaSearchParameter parameter1 = (CriteriaSearchParameter)object1;
80 final CriteriaSearchParameter parameter2 = (CriteriaSearchParameter)object2;
81
82 final int relevance1 = parameter1.getOrderRelevance();
83 final int relevance2 = parameter2.getOrderRelevance();
84 int result = 0;
85 if (relevance1 > relevance2)
86 {
87 result = 1;
88 }
89 else if (relevance1 < relevance2)
90 {
91 result = -1;
92 }
93 return result;
94 }
95 }
96
97 /**
98 * Exposes the root criteria to subclasses.
99 * @return rootCriteria
100 */
101 protected Criteria getRootCriteria()
102 {
103 return this.rootCriteria;
104 }
105
106 /**
107 * Constructor for CriteriaSearch. Creates a <code>CriteriaSearch</code> with a default
108 * <code>CriteriaSearchConfiguration</code>.
109 *
110 * @param session The Hibernate session.
111 * @param resultTypeIn The <code>Class</code> of the result.
112 */
113 public CriteriaSearch(Session session, Class resultTypeIn)
114 {
115 this.configuration = new CriteriaSearchConfiguration();
116 this.resultType = resultTypeIn;
117 this.rootCriteria = session.createCriteria(this.resultType);
118 this.childCriteriaMap = new HashMap<String, Criteria>();
119 this.orderList = new ArrayList<CriteriaSearchParameter>();
120 }
121
122 /**
123 * Executes a <code>HibernateQuery</code> using the currently defined
124 * <code>CriteriaSearchParameter</code>s, and returns a java.util.Set
125 * containing the query results.
126 *
127 * @return result The result of the query.
128 * @throws HibernateException
129 */
130 public Set executeAsSet()
131 throws HibernateException
132 {
133 return new LinkedHashSet(this.executeAsList());
134 }
135
136 /**
137 * Executes a <code>HibernateQuery</code> using the currently defined
138 * <code>CriteriaSearchParameter</code>s, and returns a java.util.List
139 * containing the query results.
140 *
141 * @return result The result of the query as a List
142 * @throws HibernateException
143 */
144 public List executeAsList()
145 throws HibernateException
146 {
147 // add ordering
148 if (this.orderList.size() > 0)
149 {
150 Collections.sort(this.orderList, new ParameterComparator());
151 for (final CriteriaSearchParameter parameter : this.orderList)
152 {
153 int direction = parameter.getOrderDirection();
154 if (direction == SearchParameter.ORDER_ASC)
155 {
156 this.getParameterCriteria(parameter).addOrder(Order.asc(this.getParameterName(parameter)));
157 }
158 else
159 {
160 this.getParameterCriteria(parameter).addOrder(Order.desc(this.getParameterName(parameter)));
161 }
162 }
163 }
164
165 // set the first result if configured
166 if (this.configuration.getFirstResult() != null)
167 {
168 this.rootCriteria.setFirstResult(this.configuration.getFirstResult().intValue());
169 }
170
171 // set the fetch size if configured
172 if (this.configuration.getFetchSize() != null)
173 {
174 this.rootCriteria.setFetchSize(this.configuration.getFetchSize().intValue());
175 }
176
177 // limit the maximum result if configured
178 if (this.configuration.getMaximumResultSize() != null)
179 {
180 this.rootCriteria.setMaxResults(this.configuration.getMaximumResultSize().intValue());
181 }
182 this.rootCriteria.setCacheable(true);
183 return this.rootCriteria.list();
184 }
185
186 /**
187 * Adds a <code>CriteriaSearchParameter</code> to this search. The parameter is connected to
188 * the search by logical <b>and</b>. It is not considered if the value is <code>null</code>.
189 * If the value is not <code>null</code> it is compared using the
190 * <code>CriteriaSearchParameter.EQUALS_COMPARATOR</code>.
191 *
192 * @param parameterValue The value of the parameter.
193 * @param parameterPattern The pattern of the parameter (dot-separated path e.g. person.address.street).
194 * @throws HibernateException
195 */
196 public void addParameter(Object parameterValue, String parameterPattern)
197 throws HibernateException
198 {
199 addParameter(new CriteriaSearchParameter(parameterValue, parameterPattern));
200 }
201
202 /**
203 * Adds a <code>CriteriaSearchParameter</code> to this search. The parameter is connected to
204 * the search by logical <b>and</b>. It is not considered if the value is <code>null</code> or
205 * if the <code>String</code> empty. If the value is not <code>null</code> it is compared
206 * using the <code>CriteriaSearchParameter.LIKE_COMPARATOR</code>.
207 *
208 * @param parameterValue The value of the parameter.
209 * @param parameterPattern The pattern of the parameter (dot-separated path e.g. person.address.street).
210 * @throws HibernateException
211 */
212 public void addParameter(String parameterValue, String parameterPattern)
213 throws HibernateException
214 {
215 addParameter(new CriteriaSearchParameter(parameterValue, parameterPattern));
216 }
217
218 /**
219 * Adds a <code>CriteriaSearchParameter</code> to this search. The parameter is connected to
220 * the search by logical <b>and</b>.
221 *
222 * @param parameter The <code>CriteriaSearchParameter</code> to add.
223 * @throws HibernateException
224 */
225 public void addParameter(CriteriaSearchParameter parameter)
226 throws HibernateException
227 {
228 if (considerParameter(parameter))
229 {
230 final Criteria parameterCriteria = this.getParameterCriteria(parameter);
231 final String parameterName = this.getParameterName(parameter);
232
233 // check the type parameter value to add
234 if(parameter.getParameterValue() instanceof Object[])
235 {
236 addExpression(
237 parameterCriteria,
238 parameterName,
239 (Object[])parameter.getParameterValue(),
240 parameter.getComparator(),
241 parameter.getMatchMode());
242 }
243 else
244 {
245 addExpression(
246 parameterCriteria,
247 parameterName,
248 parameter.getParameterValue(),
249 parameter.getComparator(),
250 parameter.getMatchMode());
251 }
252 }
253 // if the parameter is to be ordered, add it to the order list
254 if (parameter.getOrderDirection() != SearchParameter.ORDER_UNSET)
255 {
256 this.orderList.add(parameter);
257 }
258 }
259
260 /**
261 * Retrieves the appropriate criteria object for the given <code>parameter</code>.
262 *
263 * @param parameter the parameter for which to retrieve the criteria.
264 * @return the retrieved criteria.
265 */
266 private Criteria getParameterCriteria(final CriteriaSearchParameter parameter)
267 throws HibernateException
268 {
269 String[] path = CriteriaSearchParameter.PATTERN.split(parameter.getParameterPattern());
270 Criteria parameterCriteria = this.rootCriteria;
271
272 Criteria childEntityCriteria;
273 if (path.length > 1)
274 {
275 // We have a parameter affecting an attribute of an inner childEntity object so we need
276 // to traverse to get the right criteria object
277 childEntityCriteria = this.rootCriteria;
278 // Evaluating the proper criteria object for the defined parameter
279 Class type = this.resultType;
280 for (int index = 0; index < (path.length - 1); index++)
281 {
282 final String childEntityName = path[index];
283 final Collection embeddedValues = CriteriaSearchProperties.getEmbeddedValues(type);
284 if (embeddedValues != null && embeddedValues.contains(childEntityName))
285 {
286 // - use the rest of the path as the parameter name
287 final int number = path.length - index;
288 final String[] restOfPath = new String[path.length - index];
289 System.arraycopy(path, index, restOfPath, 0, number);
290 break;
291 }
292 type = CriteriaSearchProperties.getNavigableAssociationEndType(type, childEntityName);
293 childEntityCriteria = locateCriteria(childEntityName, childEntityCriteria);
294 }
295 if (childEntityCriteria != null)
296 {
297 // We now have the right criteria object
298 parameterCriteria = childEntityCriteria;
299 }
300 }
301 return parameterCriteria;
302 }
303
304 /**
305 * Retrieves the appropriate nested parameter name for the given <code>parameter</code>.
306 *
307 * @param parameter the parameter for which to retrieve the parameter name.
308 * @return the parameter name.
309 */
310 private String getParameterName(final CriteriaSearchParameter parameter)
311 {
312 // parsing the pattern of the parameter
313 String[] path = CriteriaSearchParameter.PATTERN.split(parameter.getParameterPattern());
314 String parameterName = path[path.length - 1];
315 if (path.length > 1)
316 {
317 // We have a parameter affecting an attribute of an inner childEntity object so we need
318 // to traverse to get the correct parameter name
319 // Evaluating the proper criteria object for the defined parameter
320 Class type = this.resultType;
321 for (int index = 0; index < (path.length - 1); index++)
322 {
323 final String childEntityName = path[index];
324 final Collection embeddedValues = CriteriaSearchProperties.getEmbeddedValues(type);
325 if (embeddedValues != null && embeddedValues.contains(childEntityName))
326 {
327 // - use the rest of the path as the parameter name
328 final int number = path.length - index;
329 final String[] restOfPath = new String[path.length - index];
330 System.arraycopy(path, index, restOfPath, 0, number);
331 parameterName = StringUtils.join(restOfPath, ".");
332 break;
333 }
334 type = CriteriaSearchProperties.getNavigableAssociationEndType(type, childEntityName);
335 }
336 }
337 return parameterName;
338 }
339
340 /**
341 * Decides whether a paramter is considered as a criteria for a search depending on the type and
342 * value of the <code>parameterValue</code> and <code>searchIfIsNull</code>. A
343 * <code>parameterValue</code> of the type <code>String</code> is considered
344 * <code>null</code> if being a <code>NullPointer</code> or empty.
345 *
346 * @param parameter The parameter to check.
347 */
348 private boolean considerParameter(CriteriaSearchParameter parameter)
349 {
350 if (parameter.getParameterValue() instanceof String)
351 {
352 String stringParameterValue = (String) parameter.getParameterValue();
353 return (parameter.isSearchIfNull()
354 || (stringParameterValue != null && stringParameterValue.length() > 0));
355 }
356 if (parameter.getParameterValue() instanceof Object[])
357 {
358 Object[] parameterValues = (Object[]) parameter.getParameterValue();
359 return (parameter.isSearchIfNull()
360 || (parameterValues != null && parameterValues.length > 0));
361 }
362 final int comparator = parameter.getComparator();
363 return (parameter.isSearchIfNull() ||
364 SearchParameter.NOT_NULL_COMPARATOR == comparator ||
365 SearchParameter.NULL_COMPARATOR == comparator ||
366 SearchParameter.EMPTY_COMPARATOR == comparator ||
367 SearchParameter.NOT_EMPTY_COMPARATOR == comparator) ||
368 (parameter.getParameterValue() != null);
369 }
370
371 /**
372 * Adds an <code>Restrictions</code> to a <code>Criteria</code>.
373 *
374 * @param criteria
375 * @param parameterName
376 * @param parameterValue
377 * @param comparator
378 * @param matchMode
379 */
380 private void addExpression(
381 Criteria criteria,
382 String parameterName,
383 Object parameterValue,
384 int comparator,
385 MatchMode matchMode)
386 {
387 switch (comparator)
388 {
389 case SearchParameter.NOT_NULL_COMPARATOR:
390 {
391 criteria.add(Restrictions.isNotNull(parameterName));
392 break;
393 }
394 case SearchParameter.NULL_COMPARATOR:
395 {
396 criteria.add(Restrictions.isNull(parameterName));
397 break;
398 }
399 case SearchParameter.EMPTY_COMPARATOR:
400 {
401 criteria.add(Restrictions.isEmpty(parameterName));
402 break;
403 }
404 case SearchParameter.NOT_EMPTY_COMPARATOR:
405 {
406 criteria.add(Restrictions.isNotEmpty(parameterName));
407 break;
408 }
409 default:
410 {
411 if (parameterValue != null)
412 {
413 switch (comparator)
414 {
415 case SearchParameter.LIKE_COMPARATOR:
416 {
417 if ((matchMode != null) && (parameterValue instanceof String))
418 {
419 criteria.add(Restrictions.like(
420 parameterName,
421 (String)parameterValue,
422 matchMode));
423 }
424 else
425 {
426 criteria.add(Restrictions.like(parameterName, parameterValue));
427 }
428 break;
429 }
430 case SearchParameter.NOT_LIKE_COMPARATOR:
431 {
432 SimpleExpression expression;
433 if ((matchMode != null) && (parameterValue instanceof String))
434 {
435 expression = Restrictions.like(
436 parameterName,
437 (String)parameterValue,
438 matchMode);
439 }
440 else
441 {
442 expression = Restrictions.like(parameterName, parameterValue);
443 }
444 criteria.add(Restrictions.not(expression));
445 break;
446 }
447 case SearchParameter.INSENSITIVE_LIKE_COMPARATOR:
448 {
449 if ((matchMode != null) && (parameterValue instanceof String))
450 {
451 criteria.add(Restrictions.ilike(
452 parameterName,
453 (String)parameterValue,
454 matchMode));
455 }
456 else
457 {
458 criteria.add(Restrictions.ilike(parameterName, parameterValue));
459 }
460 break;
461 }
462 case SearchParameter.NOT_INSENSITIVE_LIKE_COMPARATOR:
463 {
464 Criterion criterion;
465 if ((matchMode != null) && (parameterValue instanceof String))
466 {
467 criterion = Restrictions.ilike(
468 parameterName,
469 (String)parameterValue,
470 matchMode);
471 }
472 else
473 {
474 criterion = Restrictions.ilike(parameterName, parameterValue);
475 }
476 criteria.add(Restrictions.not(criterion));
477 break;
478 }
479 case SearchParameter.EQUAL_COMPARATOR:
480 {
481 criteria.add(Restrictions.eq(parameterName, parameterValue));
482 break;
483 }
484 case SearchParameter.GREATER_THAN_OR_EQUAL_COMPARATOR:
485 {
486 criteria.add(Restrictions.ge(parameterName, parameterValue));
487 break;
488 }
489 case SearchParameter.GREATER_THAN_COMPARATOR:
490 {
491 criteria.add(Restrictions.gt(parameterName, parameterValue));
492 break;
493 }
494 case SearchParameter.LESS_THAN_OR_EQUAL_COMPARATOR:
495 {
496 criteria.add(Restrictions.le(parameterName, parameterValue));
497 break;
498 }
499 case SearchParameter.LESS_THAN_COMPARATOR:
500 {
501 criteria.add(Restrictions.lt(parameterName, parameterValue));
502 break;
503 }
504 case SearchParameter.IN_COMPARATOR:
505 {
506 if (parameterValue instanceof Collection)
507 {
508 criteria.add(Restrictions.in(parameterName, (Collection)parameterValue));
509 }
510 break;
511 }
512 case SearchParameter.NOT_IN_COMPARATOR:
513 {
514 if (parameterValue instanceof Collection)
515 {
516 criteria.add(Restrictions.not(Restrictions.in(parameterName, (Collection)parameterValue)));
517 }
518 break;
519 }
520 case SearchParameter.NOT_EQUAL_COMPARATOR:
521 {
522 criteria.add(Restrictions.ne(parameterName, parameterValue));
523 break;
524 }
525 }
526 }
527 else
528 {
529 criteria.add(Restrictions.isNull(parameterName));
530 }
531 }
532 }
533 }
534
535 /**
536 * Adds an <code>Restrictions</code> to a <code>Criteria</code>. The given <code>parameterValues</code>
537 * represents either an array of <code>String</code> or another object. The different values in the
538 * array are added to a disjunction or conjunction which is connected with logical and to the other criteria of the
539 * search.
540 *
541 * @param criteria
542 * @param parameterName
543 * @param parameterValues
544 * @param searchIfNull
545 * @param comparator
546 * @param matchMode
547 */
548 private void addExpression(
549 Criteria criteria,
550 String parameterName,
551 Object[] parameterValues,
552 int comparator,
553 MatchMode matchMode)
554 {
555 if (parameterValues != null)
556 {
557 Disjunction disjunction = null;
558 Conjunction conjunction = null;
559 switch (comparator)
560 {
561 case SearchParameter.LIKE_COMPARATOR:
562 {
563 disjunction = Restrictions.disjunction();
564 if ((matchMode != null) && (parameterValues instanceof String[]))
565 {
566 String[] stringParameterValues = (String[]) parameterValues;
567 for (int index = 0; index < parameterValues.length; index++)
568 {
569 if (stringParameterValues[index] != null)
570 {
571 disjunction.add(Restrictions.like(
572 parameterName, stringParameterValues[index], matchMode));
573 }
574 else
575 {
576 disjunction.add(Restrictions
577 .isNull(parameterName));
578 }
579 }
580 }
581 else
582 {
583 for (int index = 0; index < parameterValues.length; index++)
584 {
585 if (parameterValues[index] != null)
586 {
587 disjunction.add(Restrictions.like(
588 parameterName, parameterValues[index]));
589 }
590 else
591 {
592 disjunction.add(Restrictions
593 .isNull(parameterName));
594 }
595 }
596 }
597 break;
598 }
599 case SearchParameter.INSENSITIVE_LIKE_COMPARATOR:
600 {
601 disjunction = Restrictions.disjunction();
602 if ((matchMode != null) && (parameterValues instanceof String[]))
603 {
604 String[] stringParameterValues = (String[]) parameterValues;
605 for (int index = 0; index < parameterValues.length; index++)
606 {
607 if (stringParameterValues[index] != null) {
608 disjunction.add(Restrictions.ilike(
609 parameterName, stringParameterValues[index], matchMode));
610 }
611 else {
612 disjunction.add(Restrictions
613 .isNull(parameterName));
614 }
615 }
616 }
617 else
618 {
619 for (int index = 0; index < parameterValues.length; index++)
620 {
621 if (parameterValues[index] != null)
622 {
623 disjunction.add(Restrictions.ilike(
624 parameterName, parameterValues[index]));
625 }
626 else
627 {
628 disjunction.add(Restrictions
629 .isNull(parameterName));
630 }
631 }
632 }
633 break;
634 }
635 case SearchParameter.EQUAL_COMPARATOR:
636 {
637 disjunction = Restrictions.disjunction();
638 for (int index = 0; index < parameterValues.length; index++)
639 {
640 if (parameterValues[index] != null)
641 {
642 disjunction.add(Restrictions.eq(parameterName,
643 parameterValues[index]));
644 }
645 else {
646 disjunction.add(Restrictions.isNull(parameterName));
647 }
648 }
649 break;
650 }
651 case SearchParameter.GREATER_THAN_OR_EQUAL_COMPARATOR:
652 {
653 disjunction = Restrictions.disjunction();
654 for (int index = 0; index < parameterValues.length; index++)
655 {
656 if (parameterValues[index] != null)
657 {
658 disjunction.add(Restrictions.ge(parameterName,
659 parameterValues[index]));
660 }
661 else
662 {
663 disjunction.add(Restrictions.isNull(parameterName));
664 }
665 }
666 break;
667 }
668 case SearchParameter.GREATER_THAN_COMPARATOR:
669 {
670 disjunction = Restrictions.disjunction();
671 for (int index = 0; index < parameterValues.length; index++)
672 {
673 if (parameterValues[index] != null)
674 {
675 disjunction.add(Restrictions.gt(parameterName,
676 parameterValues[index]));
677 }
678 else
679 {
680 disjunction.add(Restrictions.isNull(parameterName));
681 }
682 }
683 break;
684 }
685 case SearchParameter.LESS_THAN_OR_EQUAL_COMPARATOR:
686 {
687 disjunction = Restrictions.disjunction();
688 for (int index = 0; index < parameterValues.length; index++)
689 {
690 if (parameterValues[index] != null)
691 {
692 disjunction.add(Restrictions.le(parameterName,
693 parameterValues[index]));
694 }
695 else
696 {
697 disjunction.add(Restrictions.isNull(parameterName));
698 }
699 }
700 break;
701 }
702 case SearchParameter.LESS_THAN_COMPARATOR:
703 {
704 disjunction = Restrictions.disjunction();
705 for (int index = 0; index < parameterValues.length; index++)
706 {
707 if (parameterValues[index] != null)
708 {
709 disjunction.add(Restrictions.lt(parameterName,
710 parameterValues[index]));
711 }
712 else
713 {
714 disjunction.add(Restrictions.isNull(parameterName));
715 }
716 }
717 break;
718 }
719 case SearchParameter.IN_COMPARATOR:
720 {
721 criteria.add(Restrictions.in(parameterName, parameterValues));
722 break;
723 }
724 case SearchParameter.NOT_IN_COMPARATOR:
725 {
726 criteria.add(Restrictions.not(Restrictions.in(parameterName, parameterValues)));
727 break;
728 }
729 case SearchParameter.NOT_EQUAL_COMPARATOR:
730 {
731 conjunction = Restrictions.conjunction();
732 for (int index = 0; index < parameterValues.length; index++)
733 {
734 if (parameterValues[index] != null)
735 {
736 conjunction.add(Restrictions.ne(parameterName,
737 parameterValues[index]));
738 }
739 else
740 {
741 conjunction.add(Restrictions.isNotNull(parameterName));
742 }
743 }
744 break;
745 }
746 }
747
748 if (disjunction != null)
749 {
750 criteria.add(disjunction);
751 }
752 if (conjunction != null)
753 {
754 criteria.add(conjunction);
755 }
756 }
757 else
758 {
759 switch (comparator)
760 {
761 case SearchParameter.EMPTY_COMPARATOR:
762 {
763 criteria.add(Restrictions.isEmpty(parameterName));
764 break;
765 }
766 case SearchParameter.NOT_EMPTY_COMPARATOR:
767 {
768 criteria.add(Restrictions.isNotEmpty(parameterName));
769 break;
770 }
771 default:
772 {
773 criteria.add(Restrictions.isNull(parameterName));
774 }
775 }
776 }
777 }
778
779 /**
780 * Locates a <code>Criteria</code> for a <code>childEntityName</code>. If a
781 * <code>Criteria</code> exists for the <code>childEntityName</code>, it is returned. If
782 * not, one is created and referenced in the <code>childCriteriaMap</code> under the
783 * <code>childEntityName</code>.
784 *
785 * @param childEntityName
786 * @param parentCriteria
787 * @return criteria The Criteria for the childEntityName.
788 * @throws HibernateException
789 */
790 private Criteria locateCriteria(String childEntityName, Criteria parentCriteria) throws HibernateException
791 {
792 if (this.childCriteriaMap.containsKey(childEntityName))
793 {
794 return (Criteria) this.childCriteriaMap.get(childEntityName);
795 }
796 Criteria childCriteria = parentCriteria.createCriteria(childEntityName);
797 if (this.configuration.isForceEagerLoading())
798 {
799 parentCriteria.setFetchMode(childEntityName, FetchMode.JOIN);
800 }
801
802 // Hibernate does not support a 'unique' identifier. As a search may contain outer joins,
803 // duplicates in the resultList are possible. We eliminate any duplicates here, creating a
804 // distinctified resultSet (Suggestion from Hibernate itself; see www.hibernate.org's FAQ's).
805 parentCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
806 this.childCriteriaMap.put(childEntityName, childCriteria);
807 return childCriteria;
808 }
809
810 /**
811 * Returns the configuration of this search.
812 *
813 * @return configuration
814 */
815 public CriteriaSearchConfiguration getConfiguration()
816 {
817 return this.configuration;
818 }
819 }