Project

General

Profile

« Previous | Next » 

Revision 360e1668

Added by Andreas Müller almost 2 years ago

ref #9905 fix exception when matching TeamOrPersonBase

View differences:

cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/CdmGenericDaoImpl.java
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) {
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/CdmGenericDaoImplTest.java
103 103
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
104 104
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
105 105
import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
106
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
106 107
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
107 108
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
108 109
import eu.etaxonomy.cdm.model.name.Rank;
......
153 154
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
154 155
import eu.etaxonomy.cdm.persistence.dto.ReferencingObjectDto;
155 156
import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
157
import eu.etaxonomy.cdm.strategy.match.IMatchStrategy;
156 158
import eu.etaxonomy.cdm.strategy.match.IMatchStrategyEqual;
157 159
import eu.etaxonomy.cdm.strategy.match.MatchException;
160
import eu.etaxonomy.cdm.strategy.match.MatchStrategyFactory;
158 161
import eu.etaxonomy.cdm.strategy.merge.DefaultMergeStrategy;
159 162
import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy;
160 163
import eu.etaxonomy.cdm.strategy.merge.MergeException;
164
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
161 165
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
162 166
import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
163 167

  
......
1265 1269
            Assert.assertEquals(0, candidateMatchResult.size());
1266 1270
            person1.setNomenclaturalTitle("NomTitle1");  //set back
1267 1271

  
1268
            //TODO should not match in future
1269 1272
            Team teamDifferentOrder = Team.NewInstance();
1270 1273
            teamDifferentOrder.addTeamMember(person2);
1271 1274
            teamDifferentOrder.addTeamMember(person1);
......
1273 1276
            //TODO improve, should be 0 in best implementation
1274 1277
            Assert.assertEquals(1, candidateMatchResult.size());
1275 1278

  
1279
            //test that reference.authorTeam.* still works without throwing exceptions
1280
            TaxonName name = NonViralNameParserImpl.NewInstance().parseReferencedName("Abies alba Nyffeler & Eggli in Taxon 59: 232. 2010", NomenclaturalCode.ICNAFP, Rank.SPECIES());
1281
            Reference nomRef = name.getNomenclaturalReference();
1282
            IMatchStrategy referenceMatcher = MatchStrategyFactory.NewParsedReferenceInstance(nomRef);
1283
            List<Reference> matching = cdmGenericDao.findMatching(nomRef, referenceMatcher);
1284
            Assert.assertEquals("We don't expect matchings, only tested that no exceptions are thrown", 0, matching.size());
1276 1285

  
1277 1286
        } catch (IllegalArgumentException | MatchException e) {
1278 1287
            Assert.fail("No exception should be thrown");

Also available in: Unified diff