From c498522c785e64db1a6d12792fb60c94116a4fe2 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 3 Jun 2021 18:19:43 -0400 Subject: [PATCH] search by source reported incorrect size (#2705) * issue reproduced in test and fixed * changelog --- .../2705-search-by-source-incorrect-size.yaml | 4 +++ .../jpa/search/SearchCoordinatorSvcImpl.java | 4 +-- .../dao/r4/FhirResourceDaoR4SourceTest.java | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2705-search-by-source-incorrect-size.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2705-search-by-source-incorrect-size.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2705-search-by-source-incorrect-size.yaml new file mode 100644 index 00000000000..1a276fa7adf --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2705-search-by-source-incorrect-size.yaml @@ -0,0 +1,4 @@ +--- +type: fix +issue: 2705 +title: "When searching by source, if deleted resources are matched, the search returned an incorrect size. This has been corrected." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index c3dc64c610a..b4a438ebfc7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -559,9 +559,9 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { bundleProvider.setSize(count.intValue()); } else { Integer queryCount = getQueryCount(theLoadSynchronousUpTo, theParams); - if (queryCount == null || queryCount > pids.size()) { + if (queryCount == null || queryCount > resources.size()) { // No limit, last page or everything was fetched within the limit - bundleProvider.setSize(getTotalCount(queryCount, theParams.getOffset(), pids.size())); + bundleProvider.setSize(getTotalCount(queryCount, theParams.getOffset(), resources.size())); } else { bundleProvider.setSize(null); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SourceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SourceTest.java index 206ff32b7fa..955dff80c23 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SourceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SourceTest.java @@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenAndListParam; import ca.uhn.fhir.rest.param.TokenOrListParam; import ca.uhn.fhir.rest.param.TokenParam; @@ -12,6 +13,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import org.apache.commons.text.RandomStringGenerator; import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterAll; @@ -218,6 +220,31 @@ public class FhirResourceDaoR4SourceTest extends BaseJpaR4Test { } } + @Test + public void deleteWithSource() { + Patient patient = new Patient(); + String patientId = "Patient/pt-001"; + patient.setId(patientId); + String source = "urn:source:0"; + patient.getMeta().setSource(source); + patient.addName().setFamily("Presley"); + myPatientDao.update(patient); + SearchParameterMap map = SearchParameterMap.newSynchronous(); + map.add(Constants.PARAM_SOURCE, new StringParam(source)); + { + IBundleProvider result = myPatientDao.search(map); + assertThat(toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(patientId)); + } + myPatientDao.delete(new IdType(patientId)); + { + myCaptureQueriesListener.clear(); + IBundleProvider result = myPatientDao.search(map); + myCaptureQueriesListener.logSelectQueries(); + assertEquals(0, result.size()); + } + + } + public static void assertConflictException(String theResourceType, ResourceVersionConflictException e) { assertThat(e.getMessage(), matchesPattern( "Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource " + theResourceType + "/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+"));