This commit is contained in:
ianmarshall 2020-06-02 16:41:10 -04:00
commit 3f50d8e53d
6 changed files with 97 additions and 21 deletions

View File

@ -63,6 +63,7 @@ public enum VersionEnum {
V4_3_0, // 4.3.0 was renamed to 5.0.0 during the cycle V4_3_0, // 4.3.0 was renamed to 5.0.0 during the cycle
V5_0_0, V5_0_0,
V5_0_1, V5_0_1,
V5_0_2,
V5_1_0; V5_1_0;
public static VersionEnum latestVersion() { public static VersionEnum latestVersion() {

View File

@ -0,0 +1,11 @@
---
- item:
type: "add"
title: "This release corrects a snapshot dependency on org.hl7.fhir.core that was accidentally
left in HAPI FHIR 5.0.1."
- item:
type: "change"
title: "The default setting for the partition mode's Include Hashes in Search Indexes setting was
incorrectly set to true in HAPI FHIR 5.0.0 and has now been changed to false, as this is a more sensible
default. Note that this wil affect existing systems that are trying this feature out. A manual reindex of
data may be required."

View File

@ -0,0 +1,3 @@
---
release-date: "2020-06-02"
codename: "Labrador"

View File

@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -315,6 +316,55 @@ public class EmpiPersonMergerSvcTest extends BaseEmpiR4Test {
assertEquals(3, myKeepPerson.getLink().size()); assertEquals(3, myKeepPerson.getLink().size());
} }
@Test
public void testMergeNames() {
myDeletePerson.addName().addGiven("Jim");
myDeletePerson.getNameFirstRep().addGiven("George");
assertThat(myDeletePerson.getName(), hasSize(1));
assertThat(myDeletePerson.getName().get(0).getGiven(), hasSize(2));
myKeepPerson.addName().addGiven("Jeff");
myKeepPerson.getNameFirstRep().addGiven("George");
assertThat(myKeepPerson.getName(), hasSize(1));
assertThat(myKeepPerson.getName().get(0).getGiven(), hasSize(2));
mergePersons();
assertThat(myKeepPerson.getName(), hasSize(2));
assertThat(myKeepPerson.getName().get(0).getGiven(), hasSize(2));
assertThat(myKeepPerson.getName().get(1).getGiven(), hasSize(2));
}
@Test
public void testMergeNamesAllSame() {
myDeletePerson.addName().addGiven("Jim");
myDeletePerson.getNameFirstRep().addGiven("George");
assertThat(myDeletePerson.getName(), hasSize(1));
assertThat(myDeletePerson.getName().get(0).getGiven(), hasSize(2));
myKeepPerson.addName().addGiven("Jim");
myKeepPerson.getNameFirstRep().addGiven("George");
assertThat(myKeepPerson.getName(), hasSize(1));
assertThat(myKeepPerson.getName().get(0).getGiven(), hasSize(2));
mergePersons();
assertThat(myKeepPerson.getName(), hasSize(1));
assertThat(myKeepPerson.getName().get(0).getGiven(), hasSize(2));
}
@Test
public void testMergeIdentities() {
myDeletePerson.addIdentifier().setValue("aaa");
myDeletePerson.addIdentifier().setValue("bbb");
assertThat(myDeletePerson.getIdentifier(), hasSize(2));
myKeepPerson.addIdentifier().setValue("aaa");
myKeepPerson.addIdentifier().setValue("ccc");
assertThat(myKeepPerson.getIdentifier(), hasSize(2));
mergePersons();
assertThat(myKeepPerson.getIdentifier(), hasSize(3));
}
private EmpiLink createEmpiLink(Person thePerson, Patient theTargetPatient) { private EmpiLink createEmpiLink(Person thePerson, Patient theTargetPatient) {
thePerson.addLink().setTarget(new Reference(theTargetPatient)); thePerson.addLink().setTarget(new Reference(theTargetPatient));
return myEmpiLinkDaoSvc.createOrUpdateLinkEntity(thePerson, theTargetPatient, EmpiMatchResultEnum.POSSIBLE_MATCH, EmpiLinkSourceEnum.AUTO, createContextForCreate()); return myEmpiLinkDaoSvc.createOrUpdateLinkEntity(thePerson, theTargetPatient, EmpiMatchResultEnum.POSSIBLE_MATCH, EmpiLinkSourceEnum.AUTO, createContextForCreate());

View File

@ -27,10 +27,10 @@ public class PartitionSettings {
private boolean myPartitioningEnabled = false; private boolean myPartitioningEnabled = false;
private CrossPartitionReferenceMode myAllowReferencesAcrossPartitions = CrossPartitionReferenceMode.NOT_ALLOWED; private CrossPartitionReferenceMode myAllowReferencesAcrossPartitions = CrossPartitionReferenceMode.NOT_ALLOWED;
private boolean myIncludePartitionInSearchHashes = true; private boolean myIncludePartitionInSearchHashes = false;
/** /**
* If set to <code>true</code> (default is <code>true</code>) the <code>PARTITION_ID</code> value will be factored into the * If set to <code>true</code> (default is <code>false</code>) the <code>PARTITION_ID</code> value will be factored into the
* hash values used in the <code>HFJ_SPIDX_xxx</code> tables, removing the need to explicitly add a selector * hash values used in the <code>HFJ_SPIDX_xxx</code> tables, removing the need to explicitly add a selector
* on this column in queries. If set to <code>false</code>, an additional selector is used instead, which may perform * on this column in queries. If set to <code>false</code>, an additional selector is used instead, which may perform
* better when using native database partitioning features. * better when using native database partitioning features.
@ -43,7 +43,7 @@ public class PartitionSettings {
} }
/** /**
* If set to <code>true</code> (default is <code>true</code>) the <code>PARTITION_ID</code> value will be factored into the * If set to <code>true</code> (default is <code>false</code>) the <code>PARTITION_ID</code> value will be factored into the
* hash values used in the <code>HFJ_SPIDX_xxx</code> tables, removing the need to explicitly add a selector * hash values used in the <code>HFJ_SPIDX_xxx</code> tables, removing the need to explicitly add a selector
* on this column in queries. If set to <code>false</code>, an additional selector is used instead, which may perform * on this column in queries. If set to <code>false</code>, an additional selector is used instead, which may perform
* better when using native database partitioning features. * better when using native database partitioning features.

View File

@ -34,7 +34,10 @@ import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Address;
import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ContactPoint;
import org.hl7.fhir.r4.model.HumanName;
import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Person; import org.hl7.fhir.r4.model.Person;
@ -45,8 +48,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -476,15 +482,11 @@ public class PersonHelper {
private void mergeR4PersonFields(IBaseResource thePersonToDelete, IBaseResource thePersonToKeep) { private void mergeR4PersonFields(IBaseResource thePersonToDelete, IBaseResource thePersonToKeep) {
Person fromPerson = (Person) thePersonToDelete; Person fromPerson = (Person) thePersonToDelete;
Person toPerson = (Person) thePersonToKeep; Person toPerson = (Person) thePersonToKeep;
if (!toPerson.hasName()) {
toPerson.setName(fromPerson.getName()); mergeElementList(fromPerson, toPerson, HumanName.class, Person::getName, HumanName::equalsDeep);
} mergeElementList(fromPerson, toPerson, Identifier.class, Person::getIdentifier, Identifier::equalsDeep);
if (!toPerson.hasAddress()) { mergeElementList(fromPerson, toPerson, Address.class, Person::getAddress, Address::equalsDeep);
toPerson.setAddress(fromPerson.getAddress()); mergeElementList(fromPerson, toPerson, ContactPoint.class, Person::getTelecom, ContactPoint::equalsDeep);
}
if (!toPerson.hasTelecom()) {
toPerson.setTelecom(fromPerson.getTelecom());
}
if (!toPerson.hasBirthDate()) { if (!toPerson.hasBirthDate()) {
toPerson.setBirthDate(fromPerson.getBirthDate()); toPerson.setBirthDate(fromPerson.getBirthDate());
} }
@ -496,19 +498,28 @@ public class PersonHelper {
} }
} }
private <P,T> void mergeElementList(P fromPerson, P toPerson, Class<T> theBase, Function<P, List<T>> theGetList, BiPredicate<T, T> theEquals) {
List<T> fromList = theGetList.apply(fromPerson);
List<T> toList = theGetList.apply(toPerson);
List<T> itemsToAdd = new ArrayList<>();
for (T fromItem : fromList) {
if (toList.stream().noneMatch(t -> theEquals.test(fromItem, t))) {
itemsToAdd.add(fromItem);
}
}
toList.addAll(itemsToAdd);
}
private void mergeDstu3PersonFields(IBaseResource thePersonToDelete, IBaseResource thePersonToKeep) { private void mergeDstu3PersonFields(IBaseResource thePersonToDelete, IBaseResource thePersonToKeep) {
org.hl7.fhir.dstu3.model.Person fromPerson = (org.hl7.fhir.dstu3.model.Person) thePersonToDelete; org.hl7.fhir.dstu3.model.Person fromPerson = (org.hl7.fhir.dstu3.model.Person) thePersonToDelete;
org.hl7.fhir.dstu3.model.Person toPerson = (org.hl7.fhir.dstu3.model.Person) thePersonToKeep; org.hl7.fhir.dstu3.model.Person toPerson = (org.hl7.fhir.dstu3.model.Person) thePersonToKeep;
if (!toPerson.hasName()) {
toPerson.setName(fromPerson.getName()); mergeElementList(fromPerson, toPerson, org.hl7.fhir.dstu3.model.HumanName.class, org.hl7.fhir.dstu3.model.Person::getName, org.hl7.fhir.dstu3.model.HumanName::equalsDeep);
} mergeElementList(fromPerson, toPerson, org.hl7.fhir.dstu3.model.Identifier.class, org.hl7.fhir.dstu3.model.Person::getIdentifier, org.hl7.fhir.dstu3.model.Identifier::equalsDeep);
if (!toPerson.hasAddress()) { mergeElementList(fromPerson, toPerson, org.hl7.fhir.dstu3.model.Address.class, org.hl7.fhir.dstu3.model.Person::getAddress, org.hl7.fhir.dstu3.model.Address::equalsDeep);
toPerson.setAddress(fromPerson.getAddress()); mergeElementList(fromPerson, toPerson, org.hl7.fhir.dstu3.model.ContactPoint.class, org.hl7.fhir.dstu3.model.Person::getTelecom, org.hl7.fhir.dstu3.model.ContactPoint::equalsDeep);
}
if (!toPerson.hasTelecom()) {
toPerson.setTelecom(fromPerson.getTelecom());
}
if (!toPerson.hasBirthDate()) { if (!toPerson.hasBirthDate()) {
toPerson.setBirthDate(fromPerson.getBirthDate()); toPerson.setBirthDate(fromPerson.getBirthDate());
} }