diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java index 9d3ea061853..01a4acb5bd4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java @@ -473,30 +473,23 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc { // defaults to true boolean isMakeVersionCurrent = theRequestDetails == null || (boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE); + if (isMakeVersionCurrent) { - makeCodeSystemCurrentVersion(codeSystem, codeSystemToStore, conceptsToSave, totalCodeCount); + codeSystem.setCurrentVersion(codeSystemToStore); + if (codeSystem.getPid() == null) { + codeSystem = myCodeSystemDao.saveAndFlush(codeSystem); + } } - } - - - private void makeCodeSystemCurrentVersion(TermCodeSystem theCodeSystem, TermCodeSystemVersion theCodeSystemToStore, - Collection theConceptsToSave, int theTotalCodeCount) { - - theCodeSystem.setCurrentVersion(theCodeSystemToStore); - if (theCodeSystem.getPid() == null) { - theCodeSystem = myCodeSystemDao.saveAndFlush(theCodeSystem); + ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", codeSystem.getPid(), totalCodeCount); + for (TermConcept next : conceptsToSave) { + populateVersion(next, codeSystemToStore); } - ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", theCodeSystem.getPid(), theTotalCodeCount); - for (TermConcept next : theConceptsToSave) { - populateVersion(next, theCodeSystemToStore); - } - - ourLog.debug("Saving {} concepts...", theTotalCodeCount); + ourLog.debug("Saving {} concepts...", totalCodeCount); IdentityHashMap conceptsStack2 = new IdentityHashMap<>(); - for (TermConcept next : theConceptsToSave) { - persistChildren(next, theCodeSystemToStore, conceptsStack2, theTotalCodeCount); + for (TermConcept next : conceptsToSave) { + persistChildren(next, codeSystemToStore, conceptsStack2, totalCodeCount); } ourLog.debug("Done saving concepts, flushing to database"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincJpaTest.java index dbd99d5245a..c29b39c7c20 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincJpaTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincJpaTest.java @@ -111,6 +111,77 @@ public class TerminologyLoaderSvcLoincJpaTest extends BaseJpaR4Test { } + @Test + public void testLoadLoincVersionNotCurrent() throws IOException { + + // Load LOINC marked as version 2.67 + TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesWithPropertiesFileToZip(myFiles, "v267_loincupload.properties"); + + mySvc.loadLoinc(myFiles.getFiles(), mySrd); + + myTerminologyDeferredStorageSvc.saveAllDeferred(); + + // array just to make it final and populate it into following lambda + final TermCodeSystemVersion[] currentCodeSystemVersion_before_loading_v2_68 = new TermCodeSystemVersion[1]; + + runInTransaction(() -> { + assertEquals(1, myTermCodeSystemDao.count()); + assertEquals(2, myTermCodeSystemVersionDao.count()); + assertEquals(24, myTermValueSetDao.count()); + assertEquals(162, myTermConceptDao.count()); + assertEquals(12, myTermConceptMapDao.count()); + assertEquals(38, myResourceTableDao.count()); + TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri("http://loinc.org"); + + TermCodeSystemVersion myTermCodeSystemVersion_versioned = + myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.67"); + assertNotEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion_versioned.getPid()); + assertNotEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion_versioned.getResource().getId()); + + TermCodeSystemVersion myTermCodeSystemVersion_nonversioned = + myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid()); + assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion_nonversioned.getPid()); + assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion_nonversioned.getResource().getId()); + + // current should be null loaded after 2.67 + currentCodeSystemVersion_before_loading_v2_68[0] = + myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid()); + }); + + // Load LOINC marked as version 2.68 and not making it current (so 2.67 should remain current) + myFiles = new ZipCollectionBuilder(); + TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesWithPropertiesFileToZip( + myFiles, "v268_curr_false_loincupload.properties"); + mySvc.loadLoinc(myFiles.getFiles(), mySrd); + myTerminologyDeferredStorageSvc.saveAllDeferred(); + + runInTransaction(() -> { + assertEquals(1, myTermCodeSystemDao.count()); + assertEquals(3, myTermCodeSystemVersionDao.count()); + assertEquals(36, myTermValueSetDao.count()); + assertEquals(243, myTermConceptDao.count()); + assertEquals(18, myTermConceptMapDao.count()); + assertEquals(57, myResourceTableDao.count()); + TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri("http://loinc.org"); + + TermCodeSystemVersion currentCodeSystemVersion_after_loading_v2_68 = + myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid()); + + // current should be same as before loading 2.68 + assertEquals(currentCodeSystemVersion_before_loading_v2_68[0].getPid(), currentCodeSystemVersion_after_loading_v2_68.getPid()); + + TermCodeSystemVersion termCodeSystemVersion_267 = + myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.67"); + assertNotEquals(myTermCodeSystem.getCurrentVersion().getPid(), termCodeSystemVersion_267.getPid()); + + TermCodeSystemVersion termCodeSystemVersion_268 = + myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.68"); + assertNotEquals(myTermCodeSystem.getCurrentVersion().getPid(), termCodeSystemVersion_268.getPid()); + }); + + } + + /** * Loinc distro includes loinc.xml as of 2.70 */ diff --git a/hapi-fhir-jpaserver-base/src/test/resources/loinc/v268_curr_false_loincupload.properties b/hapi-fhir-jpaserver-base/src/test/resources/loinc/v268_curr_false_loincupload.properties new file mode 100644 index 00000000000..18b464c4d29 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/loinc/v268_curr_false_loincupload.properties @@ -0,0 +1,99 @@ +################# +### MANDATORY ### +################# + +# Answer lists (ValueSets of potential answers/values for LOINC "questions") +## File must be present +loinc.answerlist.file=AccessoryFiles/AnswerFile/AnswerList.csv +# Answer list links (connects LOINC observation codes to answer list codes) +## File must be present +loinc.answerlist.link.file=AccessoryFiles/AnswerFile/LoincAnswerListLink.csv + +# Document ontology +## File must be present +loinc.document.ontology.file=AccessoryFiles/DocumentOntology/DocumentOntology.csv + +# LOINC codes +## File must be present +loinc.file=LoincTable/Loinc.csv + +# LOINC hierarchy +## File must be present +loinc.hierarchy.file=AccessoryFiles/MultiAxialHierarchy/MultiAxialHierarchy.csv + +# IEEE medical device codes +## File must be present +loinc.ieee.medical.device.code.mapping.table.file=AccessoryFiles/LoincIeeeMedicalDeviceCodeMappingTable/LoincIeeeMedicalDeviceCodeMappingTable.csv + +# Imaging document codes +## File must be present +loinc.imaging.document.codes.file=AccessoryFiles/ImagingDocuments/ImagingDocumentCodes.csv + +# Part +## File must be present +loinc.part.file=AccessoryFiles/PartFile/Part.csv + +# Part link +## File must be present +loinc.part.link.primary.file=AccessoryFiles/PartFile/LoincPartLink_Primary.csv +loinc.part.link.supplementary.file=AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv + +# Part related code mapping +## File must be present +loinc.part.related.code.mapping.file=AccessoryFiles/PartFile/PartRelatedCodeMapping.csv + +# RSNA playbook +## File must be present +loinc.rsna.playbook.file=AccessoryFiles/LoincRsnaRadiologyPlaybook/LoincRsnaRadiologyPlaybook.csv + +# Top 2000 codes - SI +## File must be present +loinc.top2000.common.lab.results.si.file=AccessoryFiles/Top2000Results/SI/Top2000CommonLabResultsSi.csv +# Top 2000 codes - US +## File must be present +loinc.top2000.common.lab.results.us.file=AccessoryFiles/Top2000Results/US/Top2000CommonLabResultsUs.csv + +# Universal lab order ValueSet +## File must be present +loinc.universal.lab.order.valueset.file=AccessoryFiles/LoincUniversalLabOrdersValueSet/LoincUniversalLabOrdersValueSet.csv + +################ +### OPTIONAL ### +################ + +# This is the version identifier for the LOINC code system +## Key may be omitted if only a single version of LOINC is being kept. +loinc.codesystem.version=2.68 + +loinc.codesystem.make.current=false + +# This is the version identifier for the answer list file +## Key may be omitted +loinc.answerlist.version=Beta.1 + +# This is the version identifier for uploaded ConceptMap resources +## Key may be omitted +loinc.conceptmap.version=Beta.1 + +# Group +## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv +## File may be omitted +loinc.group.file=AccessoryFiles/GroupFile/Group.csv +# Group terms +## Default value if key not provided: AccessoryFiles/GroupFile/GroupLoincTerms.csv +## File may be omitted +loinc.group.terms.file=AccessoryFiles/GroupFile/GroupLoincTerms.csv +# Parent group +## Default value if key not provided: AccessoryFiles/GroupFile/ParentGroup.csv +## File may be omitted +loinc.parent.group.file=AccessoryFiles/GroupFile/ParentGroup.csv + +# Consumer Names +## Default value if key not provided: AccessoryFiles/ConsumerName/ConsumerName.csv +## File may be omitted +loinc.consumer.name.file=AccessoryFiles/ConsumerName/ConsumerName.csv + +# Linguistic Variants +## Default value if key not provided: AccessoryFiles/LinguisticVariants/LinguisticVariants.csv +## File may be omitted +loinc.linguistic.variants.file=AccessoryFiles/LinguisticVariants/LinguisticVariants.csv