Fix ConceptMap processing in transaction (#4442)

* failing test

* fix

* only store ConceptMap once

* remove new myPreliminaryTransactionWrite flag and use thePerformIndexing

Co-authored-by: nathaniel.doef <nathaniel.doef@smilecdr.com>
This commit is contained in:
Nathan Doef 2023-01-24 10:58:11 -05:00 committed by GitHub
parent c2b5ae6436
commit 320a0d895f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 2 deletions

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 4457
jira: SMILE-5685
title: "Previously, when a `ConceptMap` was created or updated using a transaction `Bundle`, the transaction failed with
error code `HAPI-0550: could not execute statement`. This has been fixed."

View File

@ -55,7 +55,9 @@ public class JpaResourceDaoConceptMap<T extends IBaseResource> extends JpaResour
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) { boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry); ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry);
if (!retVal.isUnchangedInCurrentOperation()) { boolean entityWasSaved = !retVal.isUnchangedInCurrentOperation();
boolean shouldProcessUpdate = entityWasSaved && thePerformIndexing;
if (shouldProcessUpdate) {
if (retVal.getDeleted() == null) { if (retVal.getDeleted() == null) {
ConceptMap conceptMap = myVersionCanonicalizer.conceptMapToCanonical(theResource); ConceptMap conceptMap = myVersionCanonicalizer.conceptMapToCanonical(theResource);
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, conceptMap); myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, conceptMap);

View File

@ -227,6 +227,7 @@ public class TermConceptMappingSvcImpl implements ITermConceptMappingSvc {
termConceptMapGroup.setSourceVersion(group.getSourceVersion()); termConceptMapGroup.setSourceVersion(group.getSourceVersion());
termConceptMapGroup.setTarget(groupTarget); termConceptMapGroup.setTarget(groupTarget);
termConceptMapGroup.setTargetVersion(group.getTargetVersion()); termConceptMapGroup.setTargetVersion(group.getTargetVersion());
termConceptMap.getConceptMapGroups().add(termConceptMapGroup);
termConceptMapGroup = myConceptMapGroupDao.save(termConceptMapGroup); termConceptMapGroup = myConceptMapGroupDao.save(termConceptMapGroup);
if (group.hasElement()) { if (group.hasElement()) {
@ -239,6 +240,7 @@ public class TermConceptMappingSvcImpl implements ITermConceptMappingSvc {
termConceptMapGroupElement.setConceptMapGroup(termConceptMapGroup); termConceptMapGroupElement.setConceptMapGroup(termConceptMapGroup);
termConceptMapGroupElement.setCode(element.getCode()); termConceptMapGroupElement.setCode(element.getCode());
termConceptMapGroupElement.setDisplay(element.getDisplay()); termConceptMapGroupElement.setDisplay(element.getDisplay());
termConceptMapGroup.getConceptMapGroupElements().add(termConceptMapGroupElement);
termConceptMapGroupElement = myConceptMapGroupElementDao.save(termConceptMapGroupElement); termConceptMapGroupElement = myConceptMapGroupElementDao.save(termConceptMapGroupElement);
if (element.hasTarget()) { if (element.hasTarget()) {
@ -252,6 +254,7 @@ public class TermConceptMappingSvcImpl implements ITermConceptMappingSvc {
termConceptMapGroupElementTarget.setCode(elementTarget.getCode()); termConceptMapGroupElementTarget.setCode(elementTarget.getCode());
termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay()); termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay());
termConceptMapGroupElementTarget.setEquivalence(elementTarget.getEquivalence()); termConceptMapGroupElementTarget.setEquivalence(elementTarget.getEquivalence());
termConceptMapGroupElement.getConceptMapGroupElementTargets().add(termConceptMapGroupElementTarget);
myConceptMapGroupElementTargetDao.save(termConceptMapGroupElementTarget); myConceptMapGroupElementTargetDao.save(termConceptMapGroupElementTarget);
if (++codesSaved % 250 == 0) { if (++codesSaved % 250 == 0) {

View File

@ -15,6 +15,7 @@ import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.term.ZipCollectionBuilder; import ca.uhn.fhir.jpa.term.ZipCollectionBuilder;
import ca.uhn.fhir.jpa.test.config.TestR4Config; import ca.uhn.fhir.jpa.test.config.TestR4Config;
import ca.uhn.fhir.jpa.util.QueryParameterUtils; import ca.uhn.fhir.jpa.util.QueryParameterUtils;
import ca.uhn.fhir.model.api.StorageResponseCodeEnum;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
@ -93,6 +94,7 @@ import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.Condition; import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.Coverage; import org.hl7.fhir.r4.model.Coverage;
import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.DateTimeType;
@ -166,7 +168,6 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.sql.DataSource;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -7657,6 +7658,57 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
assertEquals(0, results.getEntry().size()); assertEquals(0, results.getEntry().size());
} }
@Test
public void testConceptMapInTransactionBundle() {
ConceptMap conceptMap = new ConceptMap();
conceptMap.setUrl("http://www.acme.org");
conceptMap.setStatus(Enumerations.PublicationStatus.ACTIVE);
ConceptMap.ConceptMapGroupComponent group = conceptMap.addGroup();
group.setSource("http://www.some-source.ca/codeSystem/CS");
group.setTarget("http://www.some-target.ca/codeSystem/CS");
ConceptMap.SourceElementComponent source = group.addElement();
source.setCode("TEST1");
ConceptMap.TargetElementComponent target = source.addTarget();
target.setCode("TEST2");
target.setDisplay("TEST CODE");
target.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL);
Bundle requestBundle = new Bundle();
requestBundle.setType(BundleType.TRANSACTION);
Bundle.BundleEntryRequestComponent request = new Bundle.BundleEntryRequestComponent();
request.setUrl("/ConceptMap?url=http://www.acme.org");
request.setMethod(HTTPVerb.POST);
requestBundle.addEntry().setResource(conceptMap).setRequest(request);
Bundle responseBundle = myClient.transaction().withBundle(requestBundle).execute();
OperationOutcome oo = (OperationOutcome) responseBundle.getEntry().get(0).getResponse().getOutcome();
assertEquals(StorageResponseCodeEnum.SUCCESSFUL_CREATE.name(), oo.getIssueFirstRep().getDetails().getCodingFirstRep().getCode());
assertEquals(StorageResponseCodeEnum.SYSTEM, oo.getIssueFirstRep().getDetails().getCodingFirstRep().getSystem());
assertEquals(1, responseBundle.getEntry().size());
IdType id = new IdType(responseBundle.getEntry().get(0).getResponse().getLocationElement());
ConceptMap savedConceptMap = (ConceptMap) myClient.read().resource("ConceptMap").withId(id).execute();
assertEquals(conceptMap.getUrl(), savedConceptMap.getUrl());
assertEquals(conceptMap.getStatus(), savedConceptMap.getStatus());
assertEquals(1, savedConceptMap.getGroup().size());
ConceptMap.ConceptMapGroupComponent savedGroup = savedConceptMap.getGroup().get(0);
assertEquals(group.getSource(), savedGroup.getSource());
assertEquals(group.getTarget(), savedGroup.getTarget());
assertEquals(1, savedGroup.getElement().size());
ConceptMap.SourceElementComponent savedSource = savedGroup.getElement().get(0);
assertEquals(source.getCode(), savedSource.getCode());
assertEquals(1, source.getTarget().size());
ConceptMap.TargetElementComponent savedTarget = savedSource.getTarget().get(0);
assertEquals(target.getCode(), savedTarget.getCode());
assertEquals(target.getDisplay(), savedTarget.getDisplay());
assertEquals(target.getEquivalence(), savedTarget.getEquivalence());
}
@Nonnull @Nonnull
private IIdType createNewPatientWithHistory() { private IIdType createNewPatientWithHistory() {
String TEST_SYSTEM_NAME = "testHistoryRewrite"; String TEST_SYSTEM_NAME = "testHistoryRewrite";