Commit ebb86823 authored by Matija Obreza's avatar Matija Obreza

AccessionRefs can be manually re-linked, but are automatically cleared

- Aspect on delete Accession sets AccessionRef#accession to null
parent 3aa5a897
......@@ -15,9 +15,13 @@
*/
package org.genesys.catalog.service;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.genesys.catalog.exceptions.NotFoundElement;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.dataset.DatasetCreator;
import org.genesys.catalog.model.dataset.DatasetLocation;
......@@ -27,18 +31,14 @@ import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionRef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* The Interface DatasetService.
*/
......@@ -262,8 +262,19 @@ public interface DatasetService {
*/
List<Object[]> lastPublished();
/**
* Rematch dataset accessions for all datasets.
*/
void rematchDatasetAccessions();
/**
* Rematch dataset accessions.
*
* @param dataset the dataset
* @return the dataset
*/
Dataset rematchDatasetAccessions(Dataset dataset);
/**
* Create DatasetCreator for Dataset.
*
......@@ -415,4 +426,12 @@ public interface DatasetService {
*/
DatasetLocation updateLocation(Dataset dataset, DatasetLocation input) throws NotFoundElement;
/**
* Clear accession references across all Datasets for specified accessions.
*
* @param accessions the accessions
* @return the int
*/
int clearAccessionRefs(Collection<Accession> accessions);
}
......@@ -23,23 +23,25 @@ import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.querydsl.core.types.Predicate;
import org.apache.commons.lang.StringUtils;
import org.genesys.blocks.security.service.CustomAclService;
import org.genesys.catalog.exceptions.InvalidApiUsageException;
import org.genesys.catalog.exceptions.NotFoundElement;
import org.genesys.catalog.model.Partner;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.dataset.DatasetCreator;
import org.genesys.catalog.model.dataset.DatasetLocation;
import org.genesys.catalog.model.dataset.DatasetVersions;
import org.genesys.catalog.model.dataset.QDataset;
import org.genesys.catalog.model.dataset.*;
import org.genesys.catalog.model.filters.DatasetFilter;
import org.genesys.catalog.model.traits.Descriptor;
import org.genesys.catalog.persistence.dataset.DatasetCreatorRepository;
......@@ -55,7 +57,7 @@ import org.genesys.filerepository.service.RepositoryService;
import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.security.SecurityUtils;
import org.genesys2.server.service.DownloadService;
......@@ -64,16 +66,23 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
/**
......@@ -145,7 +154,7 @@ public class DatasetServiceImpl implements DatasetService {
dataset.setCrops(source.getCrops());
if (source.getAccessionRefs() != null && !source.getAccessionRefs().isEmpty()) {
dataset.setAccessionRefs(lookupMatchingAccessions(new HashSet<>(source.getAccessionRefs())));
dataset.setAccessionRefs(lookupMatchingAccessions(source.getAccessionRefs()));
}
copyDescriptors(dataset, source.getDescriptors());
......@@ -193,7 +202,7 @@ public class DatasetServiceImpl implements DatasetService {
LOG.info("Update AccessionIdentifiers. Input dataset: {}, input accessionRefs {}", dataset, accessionRefs);
dataset = loadDataset(dataset);
dataset.getAccessionRefs().clear();
dataset.setAccessionRefs(lookupMatchingAccessions(new HashSet<>(accessionRefs)));
dataset.setAccessionRefs(lookupMatchingAccessions(accessionRefs));
return lazyLoad(datasetRepository.save(dataset));
}
......@@ -466,7 +475,7 @@ public class DatasetServiceImpl implements DatasetService {
throw new NotFoundElement("Dataset doesn't exist");
}
loadedDataset.setState(PublishState.DRAFT);
loadedDataset.setAccessionRefs(lookupMatchingAccessions(new HashSet<>(accessionRefs)));
loadedDataset.setAccessionRefs(lookupMatchingAccessions(accessionRefs));
return lazyLoad(datasetRepository.save(loadedDataset));
}
......@@ -768,6 +777,7 @@ public class DatasetServiceImpl implements DatasetService {
* Looking for matching Accession and then sets that to AccessionRef
*
* @param accessionRefs the accessionRefs
*
* @return accessionRefs with matching accessions from Genesys
*/
private Set<AccessionRef> lookupMatchingAccessions(final Set<AccessionRef> accessionRefs) {
......@@ -776,20 +786,20 @@ public class DatasetServiceImpl implements DatasetService {
LOG.info("Found {} matches for {} identifiers", foundAccessions.size(), accessionRefs.size());
accessionRefs.forEach(accei -> {
accessionRefs.forEach(ref -> {
Accession foundAccession = foundAccessions.stream().filter(a -> {
return StringUtils.equalsIgnoreCase(a.getInstCode(), accei.getInstCode())
return StringUtils.equalsIgnoreCase(a.getInstCode(), ref.getInstCode())
&& (
// when DOI provided
(accei.getDoi() != null && a.getDoi() != null && StringUtils.equals(a.getDoi(), accei.getDoi()))
(ref.getDoi() != null && a.getDoi() != null && StringUtils.equals(a.getDoi(), ref.getDoi()))
// OR when without DOI
||
(StringUtils.equalsIgnoreCase(a.getAccessionNumber(), accei.getAcceNumb()) && StringUtils.equalsIgnoreCase(a.getGenus(), accei.getGenus()))
(StringUtils.equalsIgnoreCase(a.getAccessionNumber(), ref.getAcceNumb()) && StringUtils.equalsIgnoreCase(a.getGenus(), ref.getGenus()))
);
}).findFirst().orElse(null);
accei.setAccession(foundAccession);
ref.setAccession(foundAccession);
if (foundAccession == null) {
LOG.debug("No match for {}", accei);
LOG.debug("No match for {}", ref);
}
});
......@@ -799,14 +809,43 @@ public class DatasetServiceImpl implements DatasetService {
@Override
@Transactional(readOnly = false)
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void rematchDatasetAccessions() {
datasetRepository.findAll().forEach(dataset -> {
LOG.warn("Linking {} accessions with dataset {}", dataset.getAccessionCount(), dataset.getId());
dataset.setAccessionRefs(lookupMatchingAccessions(new HashSet<>(dataset.getAccessionRefs())));
datasetRepository.save(dataset);
rematchDatasetAccessions(dataset);
});
}
@Override
@Transactional(readOnly = false)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#dataset, 'write')")
public Dataset rematchDatasetAccessions(Dataset dataset) {
dataset = datasetRepository.findByUuid(dataset.getUuid());
LOG.warn("Linking {} accessions with dataset {}", dataset.getAccessionCount(), dataset.getId());
dataset.setAccessionRefs(lookupMatchingAccessions(dataset.getAccessionRefs()));
return datasetRepository.save(dataset);
}
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
public int clearAccessionRefs(Collection<Accession> accessions) {
Set<UUID> uuids = accessions.stream().map(a -> a.getUuid()).collect(Collectors.toSet());
final Iterable<Dataset> datasets = datasetRepository.findAll(dataset.accessionRefs.any().accession.in(accessions));
AtomicInteger updates = new AtomicInteger(0);
datasets.forEach(dataset -> {
dataset.getAccessionRefs().stream()
// filter for matching accessions
.filter(ref -> ref.getAccession() != null && uuids.contains(ref.getAccession().getUuid()))
// clear accession reference
.forEach(ref -> {
updates.incrementAndGet();
ref.setAccession(null);
});
});
datasetRepository.save(datasets);
return updates.get();
}
/**
* {@inheritDoc}
......
......@@ -501,23 +501,9 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU
public String getInstCode() {
return this.instituteCode;
}
// FIXME This seems a bit of a hack
public boolean getSgsv() {
return this.duplSiteStr != null && this.duplSiteStr.contains("NOR051");
}
// TODO Check if needed
public AccessionRef toAccessionRef(){
AccessionRef res = new AccessionRef();
res.setInstCode(getInstCode());
res.setGenus(getGenus());
res.setDoi(getDoi());
res.setAcceNumb(getAccessionNumber());
res.setSpecies(getTaxonomy().getSpecies());
res.setAccession((Accession) this);
return res;
}
}
......@@ -68,6 +68,23 @@ public class AccessionRef implements AccessionIdentifier3, Serializable {
@JsonView({ JsonViews.Public.class })
private Accession accession;
public AccessionRef() {
}
public AccessionRef(Accession accession) {
this.instCode = accession.getInstitute().getCode();
this.acceNumb = accession.getAccessionNumber();
this.genus = accession.getTaxonomy().getGenus();
this.doi = accession.getDoi();
this.accession = accession;
}
public AccessionRef(String instCode, String acceNumb, String genus, String doi) {
this.instCode = instCode;
this.acceNumb = acceNumb;
this.genus = genus;
this.doi = doi;
}
/**
* Gets the doi.
......@@ -271,7 +288,7 @@ public class AccessionRef implements AccessionIdentifier3, Serializable {
}
return true;
}
@Override
public String toString() {
return "AccessionRef " + instCode + " " + acceNumb + " " + genus;
......
......@@ -49,7 +49,6 @@ import org.springframework.data.elasticsearch.annotations.FieldType;
import com.fasterxml.jackson.annotation.JsonView;
// TODO: Auto-generated Javadoc
/**
* The Class Subset.
*/
......@@ -99,7 +98,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
indexes = { @Index(columnList = "subsetId, instCode, acceNumb"), @Index(columnList = "subsetId, genus") })
@Field(type = FieldType.Object)
@JsonView({ JsonViews.Public.class })
private List<AccessionRef> accessionRefs;
private Set<AccessionRef> accessionRefs;
/** The accession count. */
@Column(name = "accession_count", nullable = false)
......@@ -276,7 +275,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
*
* @return the accessionRefs
*/
public List<AccessionRef> getAccessionRefs() {
public Set<AccessionRef> getAccessionRefs() {
return accessionRefs;
}
......@@ -285,7 +284,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
*
* @param accessionRefs the new accessionRefs
*/
public void setAccessionRefs(List<AccessionRef> accessions) {
public void setAccessionRefs(Set<AccessionRef> accessions) {
this.accessionRefs = accessions;
}
......
......@@ -33,6 +33,8 @@ public interface AccessionRepositoryCustom {
List<AccessionData> findActiveAndHistoric(Collection<UUID> accessionUuids);
List<Accession> find(Collection<UUID> accessionUuids);
List<Accession> find(List<Accession> accessions);
List<Accession> findById(List<? extends AccessionIdentifier3> identifiers);
......
......@@ -45,6 +45,7 @@ import org.genesys2.server.service.impl.NonUniqueAccessionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.Querydsl;
......@@ -54,6 +55,8 @@ import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.PathBuilderFactory;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
@Repository
@Transactional(readOnly = true)
......@@ -61,6 +64,9 @@ public class AccessionRepositoryCustomImpl implements AccessionRepositoryCustom,
public static final Logger LOG = LoggerFactory.getLogger(AccessionRepositoryCustomImpl.class);
private static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[] {};
@Autowired
private JPAQueryFactory jpaQueryFactory;
@PersistenceContext
private EntityManager em;
......@@ -265,6 +271,15 @@ public class AccessionRepositoryCustomImpl implements AccessionRepositoryCustom,
return activeAndHistoric;
}
@Override
public List<Accession> find(Collection<UUID> accessionUuids) {
if (accessionUuids.isEmpty()) {
return Collections.emptyList();
}
JPAQuery<Accession> query = jpaQueryFactory.selectFrom(QAccession.accession).distinct().where(QAccession.accession.accessionId.uuid.in(accessionUuids));
return query.fetch();
}
@Override
public List<Accession> findAll(AccessionFilter filter, Pageable page) {
......
......@@ -16,13 +16,13 @@
package org.genesys2.server.service;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.genesys.catalog.exceptions.NotFoundElement;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.model.impl.SubsetCreator;
......@@ -242,4 +242,24 @@ public interface SubsetService {
List<SubsetCreator> autocompleteCreators(String text);
/**
* Rematch subset accessions across all Subsets.
*/
void rematchSubsetAccessions();
/**
* Rematch subset accessions for a Subset
*
* @param subset the subset
* @return the subset
*/
Subset rematchSubsetAccessions(Subset subset);
/**
* Clear accession references across all Subsets for specified accessions.
*
* @param accessions the accessions
* @return the int
*/
int clearAccessionRefs(Collection<Accession> accessions);
}
......@@ -16,13 +16,19 @@
package org.genesys2.server.service.impl;
import static org.genesys2.server.model.impl.QSubsetCreator.subsetCreator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.querydsl.core.types.Predicate;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.apache.commons.lang3.StringUtils;
import org.genesys.catalog.exceptions.InvalidApiUsageException;
......@@ -49,19 +55,20 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.BooleanBuilder;
import static org.genesys2.server.model.impl.QSubsetCreator.subsetCreator;
import com.querydsl.core.types.Predicate;
/**
* The Class SubsetServiceImpl.
......@@ -145,7 +152,7 @@ public class SubsetServiceImpl implements SubsetService {
* @param target the target
* @param list the subset accessions
*/
private void copyAccessions(final Subset target, final List<AccessionRef> list) {
private void copyAccessions(final Subset target, final Set<AccessionRef> list) {
if ((list == null) || (list.size() == 0)) {
if (target.getAccessionRefs() != null)
target.getAccessionRefs().clear();
......@@ -154,11 +161,11 @@ public class SubsetServiceImpl implements SubsetService {
if (target.getAccessionRefs() != null && !target.getAccessionRefs().isEmpty()) {
target.getAccessionRefs().clear();
target.getAccessionRefs().addAll(list.stream().distinct().collect(Collectors.toList()));
} else {
target.setAccessionRefs(list.stream().distinct().collect(Collectors.toList()));
target.setAccessionRefs(new HashSet<>());
}
target.getAccessionRefs().addAll(list);
}
/**
......@@ -270,10 +277,10 @@ public class SubsetServiceImpl implements SubsetService {
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#subset, 'WRITE')")
public Subset delete(final Subset subset) {
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#input, 'DELETE')")
public Subset delete(final Subset input) {
final Subset subset = loadSubset(input);
subsetRepository.delete(subset);
subset.setId(null);
return subset;
}
......@@ -293,7 +300,8 @@ public class SubsetServiceImpl implements SubsetService {
final Set<UUID> uuidsToRemove = accessions.stream().map(AccessionData::getUuid).collect(Collectors.toSet());
// Keep accessions that are not in the list
subset.setAccessionRefs(subset.getAccessionRefs().stream().filter(accessionId -> !uuidsToRemove.contains(accessionId.getAccession().getUuid())).collect(Collectors.toList()));
subset.setAccessionRefs(subset.getAccessionRefs().stream().filter(accessionId -> !uuidsToRemove.contains(accessionId.getAccession().getUuid())).collect(Collectors
.toSet()));
subset.setState(PublishState.DRAFT);
......@@ -310,15 +318,15 @@ public class SubsetServiceImpl implements SubsetService {
LOG.info("Add accessions to Subset. Input accessions {}", input);
final Subset subset = loadSubset(input);
final List<AccessionData> accessions = accessionRepository.findActiveAndHistoric(accessionsUuids);
final List<Accession> accessions = accessionRepository.find(accessionsUuids);
final Set<UUID> currentAccessions = subset.getAccessionRefs().stream().map(AccessionRef::getAccession).map(Accession::getUuid).collect(Collectors.toSet());
for (AccessionData accession : accessions) {
for (Accession accession : accessions) {
if (currentAccessions.contains(accession.getUuid())) {
LOG.warn("Current Subset already contains accession, ignoring");
} else {
subset.getAccessionRefs().add(accession.toAccessionRef());
subset.getAccessionRefs().add(new AccessionRef(accession));
currentAccessions.add(accession.getUuid());
}
}
......@@ -498,11 +506,81 @@ public class SubsetServiceImpl implements SubsetService {
target.setRole(source.getRole());
}
@Override
public List<SubsetCreator> autocompleteCreators(String text) {
final HashSet<Long> ids = new HashSet<>(securityUtils.listObjectIdentityIdsForCurrentUser(Subset.class, BasePermission.WRITE));
final Predicate predicate = subsetCreator.subset.id.in(ids).and(subsetCreator.fullName.startsWithIgnoreCase(text).or(subsetCreator.institutionalAffiliation.startsWithIgnoreCase(text)));
final Predicate predicate = subsetCreator.subset.id.in(ids).and(subsetCreator.fullName.startsWithIgnoreCase(text).or(subsetCreator.institutionalAffiliation
.startsWithIgnoreCase(text)));
return subsetCreatorRepository.findAll(predicate, new PageRequest(0, 20, new Sort("fullName"))).getContent();
}
@Override
@Transactional(readOnly = false)
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void rematchSubsetAccessions() {
subsetRepository.findAll().forEach(subset -> {
rematchSubsetAccessions(subset);
});
}
@Override
@Transactional(readOnly = false)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#subset, 'write')")
public Subset rematchSubsetAccessions(Subset subset) {
subset = subsetRepository.getByUuid(subset.getUuid());
LOG.warn("Linking {} accessions with subset {}", subset.getAccessionCount(), subset.getId());
subset.setAccessionRefs(lookupMatchingAccessions(subset.getAccessionRefs()));
return subsetRepository.save(subset);
}
/**
* Looking for matching Accession and then sets that to AccessionRef
*
* @param accessionRefs the accessionRefs
*
* @return accessionRefs with matching accessions from Genesys
*/
private Set<AccessionRef> lookupMatchingAccessions(final Set<AccessionRef> accessionRefs) {
List<AccessionRef> list = new ArrayList<>(accessionRefs);
List<Accession> foundAccessions = accessionRepository.findById(list);
LOG.info("Found {} matches for {} identifiers", foundAccessions.size(), accessionRefs.size());
accessionRefs.forEach(ref -> {
Accession foundAccession = foundAccessions.stream().filter(a -> {
return StringUtils.equalsIgnoreCase(a.getInstCode(), ref.getInstCode()) && (
// when DOI provided
(ref.getDoi() != null && a.getDoi() != null && StringUtils.equals(a.getDoi(), ref.getDoi()))
// OR when without DOI
|| (StringUtils.equalsIgnoreCase(a.getAccessionNumber(), ref.getAcceNumb()) && StringUtils.equalsIgnoreCase(a.getGenus(), ref.getGenus())));
}).findFirst().orElse(null);
ref.setAccession(foundAccession);
if (foundAccession == null) {
LOG.debug("No match for {}", ref);
}
});
return accessionRefs;
}
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
public int clearAccessionRefs(Collection<Accession> accessions) {
Set<UUID> uuids = accessions.stream().map(a -> a.getUuid()).collect(Collectors.toSet());
final Iterable<Subset> datasets = subsetRepository.findAll(QSubset.subset.accessionRefs.any().accession.in(accessions));
AtomicInteger updates = new AtomicInteger(0);
datasets.forEach(subset -> {
subset.getAccessionRefs().stream()
// filter for matching accessions
.filter(ref -> ref.getAccession() != null && uuids.contains(ref.getAccession().getUuid()))
// clear accession reference
.forEach(ref -> {
updates.incrementAndGet();