Use read partition for finding update candidate on upsert (#1945)
* Use read partition for finding update candidate on upsert * Add changelog
This commit is contained in:
parent
25fc747b9f
commit
072f3a422a
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: change
|
||||||
|
issue: 1945
|
||||||
|
title: "When performing a JPA 'upsert' (a PUT to an ID that may or may not already exist) on a partitioned system,
|
||||||
|
the partition interceptor will now be called once to determine the READ partition in order to find the candidate
|
||||||
|
resource to update, and possibly a second time to determine the CREATE partition if a new row is actually being
|
||||||
|
created. Previously only the CREATE partition was checked and used to perform the initial read."
|
|
@ -1331,10 +1331,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
*/
|
*/
|
||||||
resourceId = theResource.getIdElement();
|
resourceId = theResource.getIdElement();
|
||||||
|
|
||||||
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineCreatePartitionForRequest(theRequest, theResource, getResourceName());
|
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequest(theRequest, getResourceName());
|
||||||
try {
|
try {
|
||||||
entity = readEntityLatestVersion(resourceId, requestPartitionId);
|
entity = readEntityLatestVersion(resourceId, requestPartitionId);
|
||||||
} catch (ResourceNotFoundException e) {
|
} catch (ResourceNotFoundException e) {
|
||||||
|
requestPartitionId = myRequestPartitionHelperService.determineCreatePartitionForRequest(theRequest, theResource, getResourceName());
|
||||||
return doCreate(theResource, null, thePerformIndexing, theTransactionDetails, theRequest, requestPartitionId);
|
return doCreate(theResource, null, thePerformIndexing, theTransactionDetails, theRequest, requestPartitionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
myPartitionSettings.setAllowReferencesAcrossPartitions(PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED);
|
myPartitionSettings.setAllowReferencesAcrossPartitions(PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED);
|
||||||
|
|
||||||
// Create patient in partition 1
|
// Create patient in partition 1
|
||||||
|
addReadPartition(myPartitionId);
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addCreatePartition(myPartitionId, myPartitionDate);
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setId("ONE");
|
patient.setId("ONE");
|
||||||
|
@ -256,6 +257,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
public void testCreate_CrossPartitionReference_ByForcedId_NotAllowed() {
|
public void testCreate_CrossPartitionReference_ByForcedId_NotAllowed() {
|
||||||
|
|
||||||
// Create patient in partition 1
|
// Create patient in partition 1
|
||||||
|
addReadPartition(myPartitionId);
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addCreatePartition(myPartitionId, myPartitionDate);
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setId("ONE");
|
patient.setId("ONE");
|
||||||
|
@ -302,6 +304,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
@Test
|
@Test
|
||||||
public void testCreate_SamePartitionReference_DefaultPartition_ByForcedId() {
|
public void testCreate_SamePartitionReference_DefaultPartition_ByForcedId() {
|
||||||
// Create patient in partition NULL
|
// Create patient in partition NULL
|
||||||
|
addReadDefaultPartition();
|
||||||
addCreateDefaultPartition(myPartitionDate);
|
addCreateDefaultPartition(myPartitionDate);
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setId("ONE");
|
patient.setId("ONE");
|
||||||
|
@ -567,12 +570,14 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate_ForcedId_WithPartition() {
|
public void testCreate_ForcedId_WithPartition() {
|
||||||
|
addReadPartition(myPartitionId);
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addCreatePartition(myPartitionId, myPartitionDate);
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setId("org");
|
org.setId("org");
|
||||||
org.setName("org");
|
org.setName("org");
|
||||||
IIdType orgId = myOrganizationDao.update(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.update(org).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
addReadPartition(myPartitionId);
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addCreatePartition(myPartitionId, myPartitionDate);
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setId("pat");
|
p.setId("pat");
|
||||||
|
@ -593,12 +598,14 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate_ForcedId_NoPartition() {
|
public void testCreate_ForcedId_NoPartition() {
|
||||||
|
addReadDefaultPartition();
|
||||||
addCreateDefaultPartition();
|
addCreateDefaultPartition();
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setId("org");
|
org.setId("org");
|
||||||
org.setName("org");
|
org.setName("org");
|
||||||
IIdType orgId = myOrganizationDao.update(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.update(org).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
addReadDefaultPartition();
|
||||||
addCreateDefaultPartition();
|
addCreateDefaultPartition();
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setId("pat");
|
p.setId("pat");
|
||||||
|
@ -617,12 +624,14 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate_ForcedId_DefaultPartition() {
|
public void testCreate_ForcedId_DefaultPartition() {
|
||||||
|
addReadDefaultPartition();
|
||||||
addCreateDefaultPartition(myPartitionDate);
|
addCreateDefaultPartition(myPartitionDate);
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setId("org");
|
org.setId("org");
|
||||||
org.setName("org");
|
org.setName("org");
|
||||||
IIdType orgId = myOrganizationDao.update(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.update(org).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
addReadDefaultPartition();
|
||||||
addCreateDefaultPartition(myPartitionDate);
|
addCreateDefaultPartition(myPartitionDate);
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setId("pat");
|
p.setId("pat");
|
||||||
|
@ -691,7 +700,6 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
// Create a resource
|
// Create a resource
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addCreatePartition(myPartitionId, myPartitionDate);
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.getMeta().addTag("http://system", "code", "diisplay");
|
p.getMeta().addTag("http://system", "code", "diisplay");
|
||||||
p.setActive(true);
|
p.setActive(true);
|
||||||
|
@ -704,6 +712,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update that resource
|
// Update that resource
|
||||||
|
addReadPartition(myPartitionId);
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.setId("Patient/" + patientId);
|
p.setId("Patient/" + patientId);
|
||||||
p.setActive(false);
|
p.setActive(false);
|
||||||
|
@ -949,9 +958,9 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRead_ForcedId_SpecificPartition() {
|
public void testRead_ForcedId_SpecificPartition() {
|
||||||
IIdType patientIdNull = createPatient(withPartition(null), withActiveTrue(), withId("NULL"));
|
IIdType patientIdNull = createPatient(withPutPartition(null), withActiveTrue(), withId("NULL"));
|
||||||
IIdType patientId1 = createPatient(withPartition(1), withActiveTrue(), withId("ONE"));
|
IIdType patientId1 = createPatient(withPutPartition(1), withActiveTrue(), withId("ONE"));
|
||||||
IIdType patientId2 = createPatient(withPartition(2), withActiveTrue(), withId("TWO"));
|
IIdType patientId2 = createPatient(withPutPartition(2), withActiveTrue(), withId("TWO"));
|
||||||
|
|
||||||
// Read in correct Partition
|
// Read in correct Partition
|
||||||
addReadPartition(1);
|
addReadPartition(1);
|
||||||
|
@ -979,9 +988,9 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRead_ForcedId_DefaultPartition() {
|
public void testRead_ForcedId_DefaultPartition() {
|
||||||
IIdType patientIdNull = createPatient(withPartition(null), withActiveTrue(), withId("NULL"));
|
IIdType patientIdNull = createPatient(withPutPartition(null), withActiveTrue(), withId("NULL"));
|
||||||
IIdType patientId1 = createPatient(withPartition(1), withActiveTrue(), withId("ONE"));
|
IIdType patientId1 = createPatient(withPutPartition(1), withActiveTrue(), withId("ONE"));
|
||||||
IIdType patientId2 = createPatient(withPartition(2), withActiveTrue(), withId("TWO"));
|
IIdType patientId2 = createPatient(withPutPartition(2), withActiveTrue(), withId("TWO"));
|
||||||
|
|
||||||
// Read in correct Partition
|
// Read in correct Partition
|
||||||
addReadDefaultPartition();
|
addReadDefaultPartition();
|
||||||
|
@ -1009,9 +1018,9 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRead_ForcedId_AllPartition() {
|
public void testRead_ForcedId_AllPartition() {
|
||||||
IIdType patientIdNull = createPatient(withPartition(null), withActiveTrue(), withId("NULL"));
|
IIdType patientIdNull = createPatient(withPutPartition(null), withActiveTrue(), withId("NULL"));
|
||||||
IIdType patientId1 = createPatient(withPartition(1), withActiveTrue(), withId("ONE"));
|
IIdType patientId1 = createPatient(withPutPartition(1), withActiveTrue(), withId("ONE"));
|
||||||
createPatient(withPartition(2), withActiveTrue(), withId("TWO"));
|
createPatient(withPutPartition(2), withActiveTrue(), withId("TWO"));
|
||||||
{
|
{
|
||||||
addReadAllPartitions();
|
addReadAllPartitions();
|
||||||
IdType gotId1 = myPatientDao.read(patientIdNull, mySrd).getIdElement().toUnqualifiedVersionless();
|
IdType gotId1 = myPatientDao.read(patientIdNull, mySrd).getIdElement().toUnqualifiedVersionless();
|
||||||
|
@ -1027,9 +1036,9 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
@Test
|
@Test
|
||||||
public void testRead_ForcedId_AllPartition_WithDuplicate() {
|
public void testRead_ForcedId_AllPartition_WithDuplicate() {
|
||||||
dropForcedIdUniqueConstraint();
|
dropForcedIdUniqueConstraint();
|
||||||
IIdType patientIdNull = createPatient(withPartition(null), withActiveTrue(), withId("FOO"));
|
IIdType patientIdNull = createPatient(withPutPartition(null), withActiveTrue(), withId("FOO"));
|
||||||
IIdType patientId1 = createPatient(withPartition(1), withActiveTrue(), withId("FOO"));
|
IIdType patientId1 = createPatient(withPutPartition(1), withActiveTrue(), withId("FOO"));
|
||||||
IIdType patientId2 = createPatient(withPartition(2), withActiveTrue(), withId("FOO"));
|
IIdType patientId2 = createPatient(withPutPartition(2), withActiveTrue(), withId("FOO"));
|
||||||
assertEquals(patientIdNull, patientId1);
|
assertEquals(patientIdNull, patientId1);
|
||||||
assertEquals(patientIdNull, patientId2);
|
assertEquals(patientIdNull, patientId2);
|
||||||
|
|
||||||
|
@ -2005,7 +2014,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
public void testSearch_RefParam_TargetForcedId_SearchOnePartition() {
|
public void testSearch_RefParam_TargetForcedId_SearchOnePartition() {
|
||||||
createUniqueCompositeSp();
|
createUniqueCompositeSp();
|
||||||
|
|
||||||
IIdType patientId = createPatient(withPartition(myPartitionId), withId("ONE"), withBirthdate("2020-01-01"));
|
IIdType patientId = createPatient(withPutPartition(myPartitionId), withId("ONE"), withBirthdate("2020-01-01"));
|
||||||
IIdType observationId = createObservation(withPartition(myPartitionId), withSubject(patientId));
|
IIdType observationId = createObservation(withPartition(myPartitionId), withSubject(patientId));
|
||||||
|
|
||||||
addReadPartition(myPartitionId);
|
addReadPartition(myPartitionId);
|
||||||
|
@ -2041,7 +2050,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
public void testSearch_RefParam_TargetForcedId_SearchDefaultPartition() {
|
public void testSearch_RefParam_TargetForcedId_SearchDefaultPartition() {
|
||||||
createUniqueCompositeSp();
|
createUniqueCompositeSp();
|
||||||
|
|
||||||
IIdType patientId = createPatient(withPartition(null), withId("ONE"), withBirthdate("2020-01-01"));
|
IIdType patientId = createPatient(withPutPartition(null), withId("ONE"), withBirthdate("2020-01-01"));
|
||||||
IIdType observationId = createObservation(withPartition(null), withSubject(patientId));
|
IIdType observationId = createObservation(withPartition(null), withSubject(patientId));
|
||||||
|
|
||||||
addReadDefaultPartition();
|
addReadDefaultPartition();
|
||||||
|
@ -2073,12 +2082,24 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate_ResourcePreExistsInWrongPartition() {
|
||||||
|
IIdType patientId = createPatient(withPutPartition(null), withId("ONE"), withBirthdate("2020-01-01"));
|
||||||
|
|
||||||
|
addReadAllPartitions();
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId(patientId.toUnqualifiedVersionless());
|
||||||
|
p.setGender(Enumerations.AdministrativeGender.MALE);
|
||||||
|
myPatientDao.update(p);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHistory_Instance_CorrectPartition() {
|
public void testHistory_Instance_CorrectPartition() {
|
||||||
IIdType id = createPatient(withPartition(1), withBirthdate("2020-01-01"));
|
IIdType id = createPatient(withPartition(1), withBirthdate("2020-01-01"));
|
||||||
|
|
||||||
// Update the patient
|
// Update the patient
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addReadPartition(myPartitionId);
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setActive(false);
|
p.setActive(false);
|
||||||
p.setId(id);
|
p.setId(id);
|
||||||
|
@ -2119,7 +2140,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
IIdType id = createPatient(withPartition(1), withBirthdate("2020-01-01"));
|
IIdType id = createPatient(withPartition(1), withBirthdate("2020-01-01"));
|
||||||
|
|
||||||
// Update the patient
|
// Update the patient
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addReadPartition(myPartitionId);
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setActive(false);
|
p.setActive(false);
|
||||||
p.setId(id);
|
p.setId(id);
|
||||||
|
@ -2139,7 +2160,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
IIdType id = createPatient(withPartition(null), withBirthdate("2020-01-01"));
|
IIdType id = createPatient(withPartition(null), withBirthdate("2020-01-01"));
|
||||||
|
|
||||||
// Update the patient
|
// Update the patient
|
||||||
addCreateDefaultPartition();
|
addReadDefaultPartition();
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setActive(false);
|
p.setActive(false);
|
||||||
p.setId(id);
|
p.setId(id);
|
||||||
|
@ -2180,7 +2201,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
IIdType id = createPatient(withPartition(1), withBirthdate("2020-01-01"));
|
IIdType id = createPatient(withPartition(1), withBirthdate("2020-01-01"));
|
||||||
|
|
||||||
// Update the patient
|
// Update the patient
|
||||||
addCreatePartition(myPartitionId, myPartitionDate);
|
addReadPartition(myPartitionId);
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setActive(false);
|
p.setActive(false);
|
||||||
p.setId(id);
|
p.setId(id);
|
||||||
|
@ -2454,6 +2475,18 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Consumer<IBaseResource> withPutPartition(Integer thePartitionId) {
|
||||||
|
return t -> {
|
||||||
|
if (thePartitionId != null) {
|
||||||
|
addReadPartition(thePartitionId);
|
||||||
|
addCreatePartition(thePartitionId, null);
|
||||||
|
} else {
|
||||||
|
addReadDefaultPartition();
|
||||||
|
addCreateDefaultPartition();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Interceptor
|
@Interceptor
|
||||||
public static class MyReadWriteInterceptor extends MyWriteInterceptor {
|
public static class MyReadWriteInterceptor extends MyWriteInterceptor {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue