Fixed Ucum Conversion NullPointerException issue (#2331)

* Fixed Ucum Conversion NullPointerException issue

* Revoke:save value to the original table if it can't be normalized
This commit is contained in:
Frank Tao 2021-01-30 19:30:12 -05:00 committed by GitHub
parent 8c5b54bf54
commit 1d835d82d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 1 deletions

View File

@ -566,7 +566,7 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
assertTrue(myObservationDao.create(obs).getCreated()); assertTrue(myObservationDao.create(obs).getCreated());
// Original value should be in Quantity index, normalized should be in normalized table // The Quantity can't be normalized, it should be stored in the non normalized quantity table only
runInTransaction(() -> { runInTransaction(() -> {
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).collect(Collectors.toList()); List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).collect(Collectors.toList());
assertEquals(1, quantityIndexes.size()); assertEquals(1, quantityIndexes.size());

View File

@ -158,6 +158,7 @@ import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.util.SqlQuery;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.model.primitive.UriDt;
@ -4238,6 +4239,70 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
} }
@Test
public void testSearchWithNormalizedQuantitySearchSupported_DegreeFahrenheit() throws Exception {
myDaoConfig.getModelConfig().setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
IIdType pid0;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.setValue(new Quantity().setValueElement(new DecimalType(99.82)).setUnit("F").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("[degF]"));
myObservationDao.create(obs, mySrd);
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.setValue(new Quantity().setValueElement(new DecimalType(97.6)).setUnit("F").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("[degF]"));
myObservationDao.create(obs, mySrd);
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
// missing value
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
CodeableConcept cc = obs.getCode();
obs.setValue(new Quantity().setUnit("CM").setSystem("http://foo").setCode("cm"));
myObservationDao.create(obs, mySrd);
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
myCaptureQueriesListener.clear();
Bundle returnedBundle = myClient
.search()
.forResource(Observation.class)
.where(Observation.VALUE_QUANTITY.withPrefix(ParamPrefixEnum.EQUAL).number("99.82").andUnits("http://unitsofmeasure.org", "[degF]"))
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
assertEquals(1, returnedBundle.getEntry().size());
//-- check only use original quantity table to search
String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true,true);
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
assertThat(searchSql, not(containsString("HFJ_SPIDX_QUANTITY_NRML")));
}
@Test @Test
public void testSearchReusesNoParams() { public void testSearchReusesNoParams() {
List<IBaseResource> resources = new ArrayList<>(); List<IBaseResource> resources = new ArrayList<>();

View File

@ -93,6 +93,9 @@ public class UcumServiceUtil {
try { try {
Decimal theDecimal = new Decimal(theValue.toPlainString(), theValue.precision()); Decimal theDecimal = new Decimal(theValue.toPlainString(), theValue.precision());
theCanonicalPair = myUcumEssenceService.getCanonicalForm(new Pair(theDecimal, theCode)); theCanonicalPair = myUcumEssenceService.getCanonicalForm(new Pair(theDecimal, theCode));
// For some reason code [degF], degree Fahrenheit, can't be converted. it returns value null.
if (theCanonicalPair.getValue() == null)
return null;
} catch (UcumException e) { } catch (UcumException e) {
return null; return null;
} }

View File

@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.fhir.ucum.Pair;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class UcumServiceUtilTest { public class UcumServiceUtilTest {
@ -52,4 +53,11 @@ public class UcumServiceUtilTest {
} }
@Test
public void testUcumDegreeFahrenheit() {
assertEquals(null, UcumServiceUtil.getCanonicalForm(UcumServiceUtil.UCUM_CODESYSTEM_URL, new BigDecimal(99.82), "[degF]"));
}
} }