diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java index d9e5f62f148..19852232d69 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java @@ -56,7 +56,7 @@ public interface IAnyResource extends IBaseResource { @SearchParamDefinition( name = SP_RES_LAST_UPDATED, path = "Resource.meta.lastUpdated", - description = "The last updated date of the resource", + description = "Only return resources which were last updated as specified by the given range", type = "date") /** diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_0/6208-fix-npe-on-date.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_0/6208-fix-npe-on-date.yaml new file mode 100644 index 00000000000..c79677e3f47 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_0/6208-fix-npe-on-date.yaml @@ -0,0 +1,4 @@ +--- +type: fix +issue: 6208 +title: "A regression was temporarily introduced which caused searches by `_lastUpdated` to fail with a NullPointerException when using Lucene as the backing search engine. This has been corrected" diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java index c90a55b210c..b938a816124 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java @@ -29,6 +29,7 @@ import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.StrictErrorHandler; +import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.PreferReturnEnum; @@ -1112,6 +1113,34 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { } + @Test + public void testSearchByUrl() { + // setup + DateType dt = new DateType(new Date()); + String nowStr = dt.getValueAsString(); + + boolean storeResourceInHSearch = myStorageSettings.isStoreResourceInHSearchIndex(); + boolean advancedHSearch = myStorageSettings.isAdvancedHSearchIndexing(); + + try { + // use full text search + myStorageSettings.setStoreResourceInHSearchIndex(true); + myStorageSettings.setAdvancedHSearchIndexing(true); + + // test + Bundle b = myClient.search() + .byUrl("Patient?_lastUpdated=" + nowStr) + .returnBundle(Bundle.class) + .cacheControl(CacheControlDirective.noCache()) + .execute(); + + assertNotNull(b); + } finally { + // reset back to previous + myStorageSettings.setAdvancedHSearchIndexing(advancedHSearch); + myStorageSettings.setStoreResourceInHSearchIndex(storeResourceInHSearch); + } + } @Test public void testCreateConditionalWithPreferRepresentation() { Patient p = new Patient(); diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm index 421c2a663d9..85e6c165eb2 100644 --- a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm +++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm @@ -121,9 +121,12 @@ public class ${className}ResourceProvider extends @RawParam Map> theAdditionalRawParams, + ##DSTU2 is not an IAnyResource, yet supports LastUpdated, so we keep the magic SP in this case. + #if ( $version == 'dstu2' ) @Description(shortDefinition="Only return resources which were last updated as specified by the given range") @OptionalParam(name="_lastUpdated") - DateRangeParam theLastUpdated, + DateRangeParam the_lastUpdated, + #end @IncludeParam Set theIncludes, @@ -161,12 +164,19 @@ public class ${className}ResourceProvider extends paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_LANGUAGE, theResourceLanguage); paramMap.add("_has", theHas); -#foreach ( $param in $searchParams ) - paramMap.add("${param.name}", the${param.nameCapitalized}); +#foreach ( $param in $searchParams ) + #if( ${param.name} == "_lastUpdated") + ## Skip Last Updated since its handled by param defined below. + #else + paramMap.add("${param.name}", the${param.nameCapitalized}); + #end #end #if ( $version != 'dstu' ) - paramMap.setRevIncludes(theRevIncludes); - paramMap.setLastUpdated(theLastUpdated); +paramMap.setRevIncludes(theRevIncludes); +## Note that since we have added an SearchParamDefinition on IAnyResource for this, we had to remove +## the magic _lastUpdated that was previously hardcoded as an OperationParam. However, we still need to populate +## This special variable in the SP map. + paramMap.setLastUpdated(the_lastUpdated); #end paramMap.setIncludes(theIncludes); paramMap.setSort(theSort);