cleanup
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / TaxonServiceImpl.java
index 51743914f764cbd9648cd4c5d786ce25f542893c..09ea57c2642a491ad89657ffad6c62ddf2425b4a 100644 (file)
@@ -20,6 +20,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityNotFoundException;
 
@@ -96,8 +97,11 @@ import eu.etaxonomy.cdm.model.description.TaxonDescription;
 import eu.etaxonomy.cdm.model.description.TaxonInteraction;
 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
 import eu.etaxonomy.cdm.model.location.NamedArea;
+import eu.etaxonomy.cdm.model.media.ExternalLink;
+import eu.etaxonomy.cdm.model.media.ExternalLinkType;
 import eu.etaxonomy.cdm.model.media.Media;
 import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingEnum;
+import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingSwapEnum;
 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
 import eu.etaxonomy.cdm.model.name.IZoologicalName;
 import eu.etaxonomy.cdm.model.name.Rank;
@@ -126,6 +130,7 @@ import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;
 import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
+import eu.etaxonomy.cdm.persistence.dto.MergeResult;
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
@@ -207,59 +212,97 @@ public class TaxonServiceImpl
 
     @Override
     @Transactional(readOnly = false)
-    public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, boolean newUuidForAcceptedTaxon){
+    public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, boolean newUuidForAcceptedTaxon, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
         if (newUuidForAcceptedTaxon){
-            return swapSynonymAndAcceptedTaxonNewUuid(synonym, acceptedTaxon, setNameInSource);
+            return swapSynonymAndAcceptedTaxonNewUuid(synonym, acceptedTaxon, setNameInSource, secHandling, newSecAcc, newSecSyn);
         }else{
-            return swapSynonymAndAcceptedTaxon(synonym, acceptedTaxon, setNameInSource);
+            return swapSynonymAndAcceptedTaxon(synonym, acceptedTaxon, setNameInSource, secHandling, newSecAcc, newSecSyn);
         }
     }
 
-    private UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource){
+    private UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
         UpdateResult result = new UpdateResult();
         String oldTaxonTitleCache = acceptedTaxon.getTitleCache();
 
        TaxonName synonymName = synonym.getName();
        TaxonName taxonName = HibernateProxyHelper.deproxy(acceptedTaxon.getName());
+       Reference secAccepted = acceptedTaxon.getSec();
+       String microRefSecAccepted = acceptedTaxon.getSecMicroReference();
+       Reference secSynonym = synonym.getSec();
+        String microRefSecSynonym = synonym.getSecMicroReference();
+
+//        if (secHandling.equals(SecReferenceHandlingSwapEnum.AlwaysDelete) || (secAccepted != null && secSynonym != null && !secAccepted.getUuid().equals(secSynonym.getUuid()) && (secHandling.equals(SecReferenceHandlingSwapEnum.AlwaysSelect) || secHandling.equals(SecReferenceHandlingSwapEnum.KeepOrSelect)))){
+//            secAccepted = null;
+//            microRefSecAccepted = null;
+//            secSynonym = null;
+//            microRefSecSynonym = null;
+//        }
 
-       boolean sameHomotypicGroup = synonymName.getHomotypicalGroup().equals(taxonName.getHomotypicalGroup());
 
+       Set<ExternalLink> accLinks = new HashSet<>();
+       if (acceptedTaxon.getSecSource() != null){
+               for (ExternalLink link: acceptedTaxon.getSecSource().getLinks()){
+                accLinks.add(ExternalLink.NewInstance(ExternalLinkType.Unknown, link.getUri()));
+            }
+       }
        acceptedTaxon.setName(synonymName);
+       acceptedTaxon.setSec(newSecAcc);
+//     acceptedTaxon.setSecMicroReference(synonym.getSecMicroReference());
+
+//     if (synonym.getSecSource()!= null && synonym.getSecSource().getLinks() != null){
+//         acceptedTaxon.getSecSource().getLinks().clear();
+//             for (ExternalLink link: synonym.getSecSource().getLinks()){
+//                 acceptedTaxon.getSecSource().addLink(ExternalLink.NewInstance(ExternalLinkType.Unknown, link.getUri()));
+//            }
+//     }
+
        synonym.setName(taxonName);
+       synonym.setSec(newSecSyn);
+//        synonym.setSecMicroReference(microRefSecAccepted);
+//        if (synonym.getSecSource() != null){
+//            synonym.getSecSource().getLinks().clear();
+//            for (ExternalLink link: accLinks){
+//                synonym.getSecSource().addLink(link);
+//            }
+//        }
 
        //nameUsedInSource
        handleNameUsedInSourceForSwap(setNameInSource, taxonName, oldTaxonTitleCache, acceptedTaxon.getDescriptions());
 
-       saveOrUpdate(acceptedTaxon);
-       saveOrUpdate(synonym);
-       result.setCdmEntity(acceptedTaxon);
-       result.addUpdatedObject(synonym);
+       acceptedTaxon.resetTitleCache();
+       synonym.resetTitleCache();
+
+       MergeResult mergeTaxon = merge(acceptedTaxon, true);
+       MergeResult mergeSynonym = merge(synonym, true);
+       result.setCdmEntity((CdmBase) mergeTaxon.getMergedEntity());
+       result.addUpdatedObject((CdmBase) mergeSynonym.getMergedEntity());
 
                return result;
     }
 
-    private UpdateResult swapSynonymAndAcceptedTaxonNewUuid(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource){
+    private UpdateResult swapSynonymAndAcceptedTaxonNewUuid(Synonym oldSynonym, Taxon oldAcceptedTaxon, boolean setNameInSource, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
         UpdateResult result = new UpdateResult();
-        acceptedTaxon.removeSynonym(synonym);
-        TaxonName synonymName = synonym.getName();
-        TaxonName taxonName = HibernateProxyHelper.deproxy(acceptedTaxon.getName());
-        String oldTaxonTitleCache = acceptedTaxon.getTitleCache();
+        oldAcceptedTaxon.removeSynonym(oldSynonym);
+        TaxonName synonymName = oldSynonym.getName();
+        TaxonName taxonName = HibernateProxyHelper.deproxy(oldAcceptedTaxon.getName());
+        String oldTaxonTitleCache = oldAcceptedTaxon.getTitleCache();
 
         boolean sameHomotypicGroup = synonymName.getHomotypicalGroup().equals(taxonName.getHomotypicalGroup());
-        synonymName.removeTaxonBase(synonym);
+        synonymName.removeTaxonBase(oldSynonym);
 
         List<Synonym> synonyms = new ArrayList<>();
-        for (Synonym syn: acceptedTaxon.getSynonyms()){
+        for (Synonym syn: oldAcceptedTaxon.getSynonyms()){
             syn = HibernateProxyHelper.deproxy(syn, Synonym.class);
             synonyms.add(syn);
         }
         for (Synonym syn: synonyms){
-            acceptedTaxon.removeSynonym(syn);
+            oldAcceptedTaxon.removeSynonym(syn);
         }
-        Taxon newTaxon = acceptedTaxon.clone(true, true, false, true);
+        Taxon newTaxon = oldAcceptedTaxon.clone(true, true, false, true);
+        newTaxon.setSec(newSecAcc);
 
         //move descriptions
-        Set<TaxonDescription> descriptionsToCopy = new HashSet<>(acceptedTaxon.getDescriptions());
+        Set<TaxonDescription> descriptionsToCopy = new HashSet<>(oldAcceptedTaxon.getDescriptions());
         for (TaxonDescription description: descriptionsToCopy){
             newTaxon.addDescription(description);
         }
@@ -268,7 +311,7 @@ public class TaxonServiceImpl
 
         newTaxon.setName(synonymName);
 
-        newTaxon.setPublish(synonym.isPublish());
+        newTaxon.setPublish(oldSynonym.isPublish());
         for (Synonym syn: synonyms){
             if (!syn.getName().equals(newTaxon.getName())){
                 newTaxon.addSynonym(syn, syn.getType());
@@ -281,14 +324,14 @@ public class TaxonServiceImpl
             newTaxon.removeTaxonRelation(taxonRelationship);
         }
 
-        for(TaxonRelationship taxonRelationship : acceptedTaxon.getTaxonRelations()){
+        for(TaxonRelationship taxonRelationship : oldAcceptedTaxon.getTaxonRelations()){
             Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
             Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
-            if (fromTaxon == acceptedTaxon){
+            if (fromTaxon == oldAcceptedTaxon){
                 newTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
                         taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
 
-            }else if(toTaxon == acceptedTaxon){
+            }else if(toTaxon == oldAcceptedTaxon){
                fromTaxon.addTaxonRelation(newTaxon, taxonRelationship.getType(),
                         taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
                saveOrUpdate(fromTaxon);
@@ -305,11 +348,11 @@ public class TaxonServiceImpl
         }
 
         //taxon nodes
-        List<TaxonNode> nodes = new ArrayList<>(acceptedTaxon.getTaxonNodes());
+        List<TaxonNode> nodes = new ArrayList<>(oldAcceptedTaxon.getTaxonNodes());
         for (TaxonNode node: nodes){
             node = HibernateProxyHelper.deproxy(node);
             TaxonNode parent = node.getParent();
-            acceptedTaxon.removeTaxonNode(node);
+            oldAcceptedTaxon.removeTaxonNode(node);
             node.setTaxon(newTaxon);
             if (parent != null){
                 parent.addChildNode(node, null, null);
@@ -317,9 +360,10 @@ public class TaxonServiceImpl
         }
 
         //synonym
-        Synonym newSynonym = synonym.clone();
+        Synonym newSynonym = oldSynonym.clone();
         newSynonym.setName(taxonName);
-        newSynonym.setPublish(acceptedTaxon.isPublish());
+        newSynonym.setPublish(oldAcceptedTaxon.isPublish());
+        newSynonym.setSec(newSecSyn);
         if (sameHomotypicGroup){
             newTaxon.addSynonym(newSynonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
         }else{
@@ -333,10 +377,10 @@ public class TaxonServiceImpl
         confSyn.setDeleteNameIfPossible(false);
         result.setCdmEntity(newTaxon);
 
-        DeleteResult deleteResult = deleteTaxon(acceptedTaxon.getUuid(), conf, null);
-        if (synonym.isPersited()){
-            synonym.setSecSource(null);
-            deleteResult.includeResult(deleteSynonym(synonym.getUuid(), confSyn));
+        DeleteResult deleteResult = deleteTaxon(oldAcceptedTaxon.getUuid(), conf, null);
+        if (oldSynonym.isPersited()){
+            oldSynonym.setSecSource(null);
+            deleteResult.includeResult(deleteSynonym(oldSynonym.getUuid(), confSyn));
         }
         result.includeResult(deleteResult);
 
@@ -376,9 +420,7 @@ public class TaxonServiceImpl
             result.setAbort();
             return result;
         }
-        if (secHandling != null && secHandling.equals(SecReferenceHandlingEnum.KeepAlways)){
-            newSecRef = synonym.getSec();
-        }
+
         Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, newSecRef, microRef);
         newAcceptedTaxon.setPublish(synonym.isPublish());
         dao.save(newAcceptedTaxon);
@@ -387,7 +429,7 @@ public class TaxonServiceImpl
         List<Synonym> heteroSynonyms = acceptedTaxon.getSynonymsInGroup(synonymHomotypicGroup);
 
         for (Synonym heteroSynonym : heteroSynonyms){
-            if (secHandling == null || !secHandling.equals(SecReferenceHandlingEnum.KeepAlways)){
+            if (secHandling == null){
                 heteroSynonym.setSec(newSecRef);
             }
             if (synonym.equals(heteroSynonym)){
@@ -433,21 +475,19 @@ public class TaxonServiceImpl
             case AlwaysDelete:
                 newSecRef = null;
                 break;
-            case KeepAlways:
-                break;
             case UseNewParentSec:
                 newSecRef = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null;
                 break;
-            case KeepWhenSame:
+            case KeepOrWarn:
                 Reference parentSec = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null;
                 Reference synSec = synonym.getSec();
-                if (parentSec != null && synSec != null && parentSec.equals(synSec)){
-                    newSecRef = synonym.getSec();
+                if (synSec != null ){
+                    newSecRef = CdmBase.deproxy(synSec);
                 }else{
                     newSecRef = CdmBase.deproxy(referenceService.load(newSec));
                 }
                 break;
-            case WarningSelect:
+            case KeepOrSelect:
                 newSecRef = CdmBase.deproxy(referenceService.load(newSec));
                 break;
             default:
@@ -938,7 +978,7 @@ public class TaxonServiceImpl
     //    logger.setLevel(Level.TRACE);
 //        Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
 
-        logger.trace("listMedia() - START");
+        if (logger.isTraceEnabled()){logger.trace("listMedia() - START");}
 
         Set<Taxon> taxa = new HashSet<>();
         List<Media> taxonMedia = new ArrayList<>();
@@ -950,14 +990,14 @@ public class TaxonServiceImpl
 
         // --- resolve related taxa
         if (includeRelationships != null && ! includeRelationships.isEmpty()) {
-            logger.trace("listMedia() - resolve related taxa");
+            if (logger.isTraceEnabled()){logger.trace("listMedia() - resolve related taxa");}
             taxa = listRelatedTaxa(taxon, includeRelationships, null, includeUnpublished, null, null, null);
         }
 
         taxa.add((Taxon) dao.load(taxon.getUuid()));
 
         if(includeTaxonDescriptions != null && includeTaxonDescriptions){
-            logger.trace("listMedia() - includeTaxonDescriptions");
+            if (logger.isTraceEnabled()){logger.trace("listMedia() - includeTaxonDescriptions");}
             List<TaxonDescription> taxonDescriptions = new ArrayList<>();
             // --- TaxonDescriptions
             for (Taxon t : taxa) {
@@ -983,7 +1023,7 @@ public class TaxonServiceImpl
 
 
         if(includeOccurrences != null && includeOccurrences) {
-            logger.trace("listMedia() - includeOccurrences");
+            if (logger.isTraceEnabled()){logger.trace("listMedia() - includeOccurrences");}
             @SuppressWarnings("rawtypes")
             Set<SpecimenOrObservationBase> specimensOrObservations = new HashSet<>();
             // --- Specimens
@@ -1017,16 +1057,16 @@ public class TaxonServiceImpl
                     }
                 }
                 //media in hierarchy
-                taxonMedia.addAll(occurrenceService.getMediainHierarchy(occurrence, null, null, propertyPath).getRecords());
+                taxonMedia.addAll(occurrenceService.getMediaInHierarchy(occurrence, null, null, propertyPath).getRecords());
             }
         }
 
         if(includeTaxonNameDescriptions != null && includeTaxonNameDescriptions) {
-            logger.trace("listMedia() - includeTaxonNameDescriptions");
+            if (logger.isTraceEnabled()){logger.trace("listMedia() - includeTaxonNameDescriptions");}
             // --- TaxonNameDescription
             Set<TaxonNameDescription> nameDescriptions = new HashSet<>();
             for (Taxon t : taxa) {
-                nameDescriptions .addAll(t.getName().getDescriptions());
+                nameDescriptions.addAll(t.getName().getDescriptions());
             }
             for(TaxonNameDescription nameDescription: nameDescriptions){
                 if (!limitToGalleries || nameDescription.isImageGallery()) {
@@ -1040,14 +1080,20 @@ public class TaxonServiceImpl
             }
         }
 
-        logger.trace("listMedia() - initialize");
+        taxonMedia = deduplicateMedia(taxonMedia);
+
+        if (logger.isTraceEnabled()){logger.trace("listMedia() - initialize");}
         beanInitializer.initializeAll(taxonMedia, propertyPath);
 
-        logger.trace("listMedia() - END");
+        if (logger.isTraceEnabled()){logger.trace("listMedia() - END");}
 
         return taxonMedia;
     }
 
+    private List<Media> deduplicateMedia(List<Media> taxonMedia) {
+        return taxonMedia.stream().distinct().collect(Collectors.toList());
+    }
+
     @Override
     public List<TaxonBase> findTaxaByID(Set<Integer> listOfIDs) {
         return this.dao.loadList(listOfIDs, null, null);
@@ -1306,13 +1352,14 @@ public class TaxonServiceImpl
             //remove name if possible (and required)
             if (name != null && config.isDeleteNameIfPossible()){
 
-                    DeleteResult nameDeleteResult = nameService.delete(name, config.getNameDeletionConfig());
-                    if (nameDeleteResult.isAbort() || nameDeleteResult.isError()){
-                       result.addExceptions(nameDeleteResult.getExceptions());
-                       result.addRelatedObject(name);
-                    }else{
-                        result.addDeletedObject(name);
-                    }
+                DeleteResult nameDeleteResult = nameService.delete(name, config.getNameDeletionConfig());
+                if (nameDeleteResult.isAbort() || nameDeleteResult.isError()){
+                       result.addExceptions(nameDeleteResult.getExceptions());
+                       result.addRelatedObject(name);
+                       result.addUpdatedObject(name);
+                }else{
+                    result.addDeletedObject(name);
+                }
             }
         }
         return result;
@@ -1544,6 +1591,8 @@ public class TaxonServiceImpl
 
         result.addUpdatedObject(oldTaxon);
         result.addUpdatedObject(newTaxon);
+        result.addUpdatedObject(homotypicGroup);
+        result.addUpdatedObject(synonym);
         saveOrUpdate(oldTaxon);
         saveOrUpdate(newTaxon);
 
@@ -1577,7 +1626,7 @@ public class TaxonServiceImpl
         }
 
         Map<CdmBaseType, String> idFieldMap = new HashMap<>();
-        idFieldMap.put(CdmBaseType.TAXON, "id");
+        idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
 
         // ---  initialize taxa, thighlight matches ....
         ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
@@ -1645,7 +1694,7 @@ public class TaxonServiceImpl
         }
 
         Map<CdmBaseType, String> idFieldMap = new HashMap<>();
-        idFieldMap.put(CdmBaseType.TAXON, "id");
+        idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
 
         // ---  initialize taxa, thighlight matches ....
         ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
@@ -1722,7 +1771,7 @@ public class TaxonServiceImpl
      * Uses org.apache.lucene.search.join.JoinUtil for query time joining, alternatively
      * the BlockJoinQuery could be used. The latter might be more memory save but has the
      * drawback of requiring to do the join an indexing time.
-     * see  http://dev.e-taxonomy.eu/trac/wiki/LuceneNotes#JoinsinLucene for more information on this.
+     * see  https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/LuceneNotes#JoinsinLucene for more information on this.
      *
      * Joins TaxonRelationShip with Taxon depending on the direction of the given edge:
      * <ul>
@@ -1811,11 +1860,12 @@ public class TaxonServiceImpl
             Set<NamedArea> namedAreas, Set<PresenceAbsenceTerm> distributionStatus, List<Language> languages,
             boolean highlightFragments, Integer pageSize,
             Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)
-            throws IOException, LuceneParseException, LuceneMultiSearchException {
+                    throws IOException, LuceneParseException, LuceneMultiSearchException {
 
         // FIXME: allow taxonomic ordering
-        //  hql equivalent:  order by t.name.genusOrUninomial, case when t.name.specificEpithet like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";
-        // this require building a special sort column by a special classBridge
+        //  hql equivalent:  order by t.name.genusOrUninomial, case when t.name.specificEpithet
+        // like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";
+        // this requires building a special sort column by a special classBridge
         if(highlightFragments){
             logger.warn("findTaxaAndNamesByFullText() : fragment highlighting is " +
                     "currently not fully supported by this method and thus " +
@@ -1914,7 +1964,7 @@ public class TaxonServiceImpl
             luceneSearches.add(prepareFindByFullTextSearch(taxonBaseSubclass,
                     queryString, classification, subtree, className,
                     includeUnpublished, languages, highlightFragments, sortFields));
-            idFieldMap.put(CdmBaseType.TAXON, "id");
+            idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
             /* A) does not work!!!!
             if(addDistributionFilter){
                 // in this case we need a filter which uses a join query
@@ -1966,7 +2016,7 @@ public class TaxonServiceImpl
             byCommonNameSearch.setQuery(builder.build());
             byCommonNameSearch.setSortFields(sortFields);
 
-            idFieldMap.put(CdmBaseType.TAXON, "id");
+            idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
 
             luceneSearches.add(byCommonNameSearch);
 
@@ -2009,7 +2059,7 @@ public class TaxonServiceImpl
             luceneSearches.add(prepareFindByTaxonRelationFullTextSearch(
                     new TaxonRelationshipEdge(relTypes, Direction.relatedTo),
                     queryString, classification, subtree, includeUnpublished, languages, highlightFragments, sortFields));
-            idFieldMap.put(CdmBaseType.TAXON, "id");
+            idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
 
             if(addDistributionFilter){
                 String fromField = "inDescription.taxon.id"; // in DescriptionElementBase index
@@ -2064,7 +2114,7 @@ public class TaxonServiceImpl
             luceneSearches.add(prepareFindByTaxonRelationFullTextSearch(
                     new TaxonRelationshipEdge(relTypes, Direction.relatedTo),
                     queryString, classification, subtree, includeUnpublished, languages, highlightFragments, sortFields));
-            idFieldMap.put(CdmBaseType.TAXON, "id");
+            idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
 
             if(addDistributionFilter){
                 String fromField = "inDescription.taxon.id"; // in DescriptionElementBase index
@@ -2272,7 +2322,7 @@ public class TaxonServiceImpl
         ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(multiSearch, multiSearch.getQuery());
 
         Map<CdmBaseType, String> idFieldMap = new HashMap<>();
-        idFieldMap.put(CdmBaseType.TAXON, "id");
+        idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
         idFieldMap.put(CdmBaseType.DESCRIPTION_ELEMENT, "inDescription.taxon.id");
 
         List<SearchResult<TaxonBase>> searchResults = searchResultBuilder.createResultSet(
@@ -3032,7 +3082,6 @@ public class TaxonServiceImpl
         Taxon toTaxon = (Taxon) dao.load(toTaxonUuid);
         result = changeRelatedTaxonToSynonym(fromTaxon, toTaxon, oldRelationshipType, synonymType);
 
-//        result.addUpdatedObject(fromTaxon);
         result.addUpdatedObject(toTaxon);
         result.addUpdatedObject(result.getCdmEntity());
 
@@ -3098,10 +3147,11 @@ public class TaxonServiceImpl
         }else{
             SynonymDeletionConfigurator synonymConfig = (SynonymDeletionConfigurator) config;
             result = isDeletableForSynonym(references, synonymConfig);
-            if (synonymConfig.isDeleteNameIfPossible()){
+            if (synonymConfig.isDeleteNameIfPossible() && taxonBase.getName() != null){
                 DeleteResult nameResult = nameService.isDeletable(taxonBase.getName().getUuid(), synonymConfig.getNameDeletionConfig(), taxonBase.getUuid());
                 if (!nameResult.isOk()){
                     result.addExceptions(nameResult.getExceptions());
+
                 }
             }
         }
@@ -3415,13 +3465,16 @@ public class TaxonServiceImpl
        @Override
        @Transactional(readOnly = false)
        public UpdateResult swapSynonymAndAcceptedTaxon(UUID synonymUUid,
-                       UUID acceptedTaxonUuid, boolean setNameInSource, boolean newUuidForAcceptedTaxon) {
+                       UUID acceptedTaxonUuid, boolean setNameInSource, boolean newUuidForAcceptedTaxon, SecReferenceHandlingSwapEnum secHandling, UUID newSecAcc, UUID newSecSyn) {
                TaxonBase<?> base = this.load(synonymUUid);
                Synonym syn = HibernateProxyHelper.deproxy(base, Synonym.class);
                base = this.load(acceptedTaxonUuid);
                Taxon taxon = HibernateProxyHelper.deproxy(base, Taxon.class);
 
-               return this.swapSynonymAndAcceptedTaxon(syn, taxon, setNameInSource, newUuidForAcceptedTaxon);
+               Reference refAcc = referenceService.load(newSecAcc);
+               Reference refSyn = referenceService.load(newSecSyn);
+
+               return this.swapSynonymAndAcceptedTaxon(syn, taxon, setNameInSource, newUuidForAcceptedTaxon, secHandling, refAcc, refSyn);
        }
 
     @Override