From e3a2dc2fac59706493e11f7234439216b8a74008 Mon Sep 17 00:00:00 2001 From: yalingpei Date: Tue, 18 Nov 2025 12:10:28 -0800 Subject: [PATCH 1/3] [7384] Fix chained reference search error caused by enabling MDM expansion --- .../jpa/cache/ResourceChangeListenerCacheRefresherImpl.java | 2 +- .../main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java index 2f8940f698a2..7fd43114c25d 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java @@ -82,7 +82,7 @@ public static class Job implements HapiJob { @Override public void execute(JobExecutionContext theContext) { - myTarget.refreshExpiredCachesAndNotifyListeners(); + // myTarget.refreshExpiredCachesAndNotifyListeners(); } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java index f762d2b756b4..ca460565ed97 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java @@ -146,7 +146,7 @@ private void expandAnyReferenceParameters( List toRemove = new ArrayList<>(); List toAdd = new ArrayList<>(); for (IQueryParameterType iQueryParameterType : orList) { - if (iQueryParameterType instanceof ReferenceParam refParam) { + if (iQueryParameterType instanceof ReferenceParam refParam && !refParam.hasChain()) { if (theParamTester.shouldExpand(theParamName, refParam)) { ourLog.debug("Found a reference parameter to expand: {}", refParam); // First, attempt to expand as a source resource. From 628417a54b19e1cefb539ae1089100811c369ef8 Mon Sep 17 00:00:00 2001 From: yalingpei Date: Tue, 18 Nov 2025 12:37:50 -0800 Subject: [PATCH 2/3] [7384] add changelog and tests --- ...ference-search-error-on-mdm-expansion.yaml | 8 +++++ .../MdmSearchExpandingInterceptorIT.java | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/8_8_0/7384-fix-chained-reference-search-error-on-mdm-expansion.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/8_8_0/7384-fix-chained-reference-search-error-on-mdm-expansion.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/8_8_0/7384-fix-chained-reference-search-error-on-mdm-expansion.yaml new file mode 100644 index 000000000000..5144e999594c --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/8_8_0/7384-fix-chained-reference-search-error-on-mdm-expansion.yaml @@ -0,0 +1,8 @@ +--- +type: fix +issue: 7384 +jira: SMILE-11171 +title: "When MDM expansion search was enabled, search operations with chained references returned 404 Not Found errors. + The OperationOutcome in the response indicated that the wrong resource name had been used for the search. + This issue has now been resolved. + " diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSearchExpandingInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSearchExpandingInterceptorIT.java index 038eaea19fb0..bcc5e0cce6b4 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSearchExpandingInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSearchExpandingInterceptorIT.java @@ -19,6 +19,7 @@ import ca.uhn.fhir.rest.param.TokenParam; import jakarta.servlet.http.HttpServletRequest; import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.AllergyIntolerance; import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Patient; @@ -26,6 +27,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; +import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; @@ -36,10 +38,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.slf4j.LoggerFactory.getLogger; @ContextConfiguration(classes = {MdmHelperConfig.class}) public class MdmSearchExpandingInterceptorIT extends BaseMdmR4Test { + private static final Logger ourLog = getLogger(MdmSearchExpandingInterceptorIT.class); + @RegisterExtension @Autowired public MdmHelperR4 myMdmHelper; @@ -266,6 +271,32 @@ public void testReferenceExpansionQuietlyFailsOnMissingMdmMatches() throws Inter assertEquals(1, search.size()); } + @Test + public void testChainedReferenceSearch_whenMdmExpansionEnabled_shouldGetSearchResult() throws InterruptedException { + // setup + myStorageSettings.setAllowMdmExpansion(true); + + Patient patient = buildResource(("Patient"), withIdentifier("http://foo.bar/test", "abc")); + String pid = myMdmHelper.executeWithLatch(() -> myMdmHelper.doCreateResource(patient, true)).getId().getIdPart(); + AllergyIntolerance allergy = new AllergyIntolerance(); + allergy.setPatient(new Reference("Patient/" + pid)); + doCreateResource(allergy); + + SearchParameterMap paramMap = new SearchParameterMap(); + ReferenceParam param = new ReferenceParam("identifier", "http://foo.bar/test|abc"); + param.setValueAsQueryToken(myFhirContext, "patient", ":Patient.identifier", "http://foo.bar/test|abc"); + paramMap.add("patient", param); + + // execute + myCaptureQueriesListener.clear(); + IBundleProvider search = myAllergyIntoleranceDao.search(paramMap, mySrd); + myCaptureQueriesListener.logAllQueriesForCurrentThread(); + + // validate + assertEquals(1, search.size()); + ourLog.info(myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true)); + } + private Observation createObservationWithSubject(String thePatientId) { Observation observation = new Observation(); observation.setSubject(new Reference("Patient/" + thePatientId)); From bc35e27fc5af3d5b96523a058d7116f9f7c07b00 Mon Sep 17 00:00:00 2001 From: yalingpei Date: Tue, 18 Nov 2025 12:49:34 -0800 Subject: [PATCH 3/3] [7384] revert unintended change --- .../jpa/cache/ResourceChangeListenerCacheRefresherImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java index 7fd43114c25d..2f8940f698a2 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeListenerCacheRefresherImpl.java @@ -82,7 +82,7 @@ public static class Job implements HapiJob { @Override public void execute(JobExecutionContext theContext) { - // myTarget.refreshExpiredCachesAndNotifyListeners(); + myTarget.refreshExpiredCachesAndNotifyListeners(); } }