666 |
666 |
Class<?> matchClass = objectToMatch.getClass();
|
667 |
667 |
ClassMetadata classMetaData = session.getSessionFactory().getClassMetadata(matchClass.getCanonicalName());
|
668 |
668 |
Criteria criteria = session.createCriteria(matchClass);
|
669 |
|
boolean noMatch = makeCriteria(objectToMatch, matchStrategy, classMetaData, criteria);
|
|
669 |
boolean noMatch = makeCriteria(objectToMatch, matchStrategy, classMetaData, criteria, 1);
|
670 |
670 |
if (logger.isDebugEnabled()){logger.debug(criteria);}
|
671 |
671 |
//session.flush();
|
672 |
672 |
if (noMatch == false){
|
... | ... | |
692 |
692 |
* @param matchStrategy the match strategy used
|
693 |
693 |
* @param classMetaData the precomputed class metadata
|
694 |
694 |
* @param criteria the criteria to fill
|
|
695 |
* @param level recursion level
|
695 |
696 |
* @return <code>true</code> if definitely no matching object will be found,
|
696 |
697 |
* <code>false</code> if nothing is known on the existence of a matching result
|
697 |
698 |
*/
|
698 |
699 |
private boolean makeCriteria(Object objectToMatch,
|
699 |
700 |
IMatchStrategy matchStrategy, ClassMetadata classMetaData,
|
700 |
|
Criteria criteria) throws IllegalAccessException, MatchException {
|
|
701 |
Criteria criteria, int level) throws IllegalAccessException, MatchException {
|
701 |
702 |
|
702 |
703 |
Matching matching = matchStrategy.getMatching((IMatchable)objectToMatch);
|
703 |
704 |
boolean noMatch = false;
|
... | ... | |
745 |
746 |
if (propertyType.isComponentType()){
|
746 |
747 |
matchComponentType(criteria, fieldMatcher, propertyName, value, matchModes);
|
747 |
748 |
}else{
|
748 |
|
noMatch = matchNonComponentType(criteria, fieldMatcher, propertyName, value, matchModes, propertyType);
|
|
749 |
noMatch = matchNonComponentType(criteria, fieldMatcher, propertyName, value, matchModes, propertyType, level);
|
749 |
750 |
}
|
750 |
751 |
}
|
751 |
752 |
if (noMatch){
|
... | ... | |
779 |
780 |
}
|
780 |
781 |
}
|
781 |
782 |
|
|
783 |
/**
|
|
784 |
* @param level the recursion level
|
|
785 |
*/
|
782 |
786 |
private boolean matchNonComponentType(Criteria criteria,
|
783 |
787 |
FieldMatcher fieldMatcher,
|
784 |
788 |
String propertyName,
|
785 |
789 |
Object value,
|
786 |
790 |
List<MatchMode> matchModes,
|
787 |
|
Type propertyType)
|
|
791 |
Type propertyType, int level)
|
788 |
792 |
throws HibernateException, DataAccessException, MatchException, IllegalAccessException{
|
789 |
793 |
|
790 |
794 |
boolean noMatch = false;
|
... | ... | |
798 |
802 |
if (propertyType.isCollectionType()){
|
799 |
803 |
if (value instanceof Collection) {
|
800 |
804 |
//TODO fieldMatcher?
|
801 |
|
matchCollection(criteria, propertyName, (Collection<?>)value);
|
|
805 |
matchCollection(criteria, propertyName, (Collection<?>)value, level);
|
802 |
806 |
|
803 |
807 |
}else if (value instanceof Map) {
|
804 |
808 |
//TODO map not yet handled for match
|
... | ... | |
816 |
820 |
if (IMatchable.class.isAssignableFrom(matchClass)){
|
817 |
821 |
IMatchStrategy valueMatchStrategy = fieldMatcher.getMatchStrategy() != null? fieldMatcher.getMatchStrategy() : DefaultMatchStrategy.NewInstance(matchClass);
|
818 |
822 |
ClassMetadata valueClassMetaData = getSession().getSessionFactory().getClassMetadata(matchClass.getCanonicalName());
|
819 |
|
noMatch = makeCriteria(value, valueMatchStrategy, valueClassMetaData, matchCriteria);
|
|
823 |
noMatch = makeCriteria(value, valueMatchStrategy, valueClassMetaData, matchCriteria, level+1);
|
820 |
824 |
}else{
|
821 |
825 |
logger.error("Class to match (" + matchClass + ") is not of type IMatchable");
|
822 |
826 |
throw new MatchException("Class to match (" + matchClass + ") is not of type IMatchable");
|
... | ... | |
839 |
843 |
* class Person it checks that there is at least 1 person matching in
|
840 |
844 |
* nomenclaturalTitle, no matter at which position.
|
841 |
845 |
* See #9905 and #9964
|
|
846 |
*
|
|
847 |
* @param level recursion level
|
842 |
848 |
*/
|
843 |
|
private void matchCollection(Criteria criteria, String propertyName, Collection<?> collection) {
|
|
849 |
private void matchCollection(Criteria criteria, String propertyName, Collection<?> collection, int level) {
|
844 |
850 |
int i = 0;
|
|
851 |
//this is a workaround to avoid handling TeamOrPersonBase e.g. in references.
|
|
852 |
//TeamOrPersonBase does not have a property 'teamMembers' and therefore an
|
|
853 |
//according restriction can not be added
|
|
854 |
if (level > 1) {
|
|
855 |
return;
|
|
856 |
}
|
845 |
857 |
|
846 |
858 |
criteria.add(Restrictions.sizeEq(propertyName, collection.size()));
|
847 |
859 |
|
... | ... | |
849 |
861 |
// criteria.createAlias(propertyName, propertyAlias);
|
850 |
862 |
//In future (hibernate >5.1 JPA will allow using index joins: https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/criteria-api-collection-operations.html
|
851 |
863 |
// Criteria subCriteria = criteria.createCriteria(propertyName+"[1]");
|
|
864 |
|
852 |
865 |
Criteria subCriteria = criteria.createCriteria(propertyName);
|
853 |
866 |
|
854 |
867 |
for (Object single : collection) {
|
ref #9905 fix exception when matching TeamOrPersonBase