diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/HapiExtensions.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/HapiExtensions.java index 63121a0885d..3bd696d19f0 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/HapiExtensions.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/HapiExtensions.java @@ -113,8 +113,9 @@ public class HapiExtensions { /** * URL for boolean extension added to all placeholder resources + * + * @deprecated Deprecated in 5.4.0 in favour of {@link HapiExtensions#EXT_RESOURCE_PLACEHOLDER} */ - // FIXME: DM 2021-03-04 - This should probably be removed, and replaced with EXT_RESOURCE_PLACEHOLDER above. public static final String EXT_RESOURCE_META_PLACEHOLDER = "http://hapifhir.io/fhir/StructureDefinition/resource-meta-placeholder"; diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java index 25106646a56..c791f38fde5 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java +++ b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java @@ -186,9 +186,11 @@ public class DaoConfig { private int myPreExpandValueSetsMaxCount = 1000; /** + * Do not change default of {@code true}! + * * @since 4.2.0 */ - private boolean myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets; + private boolean myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets = true; /** * @since 5.0.0 @@ -1102,7 +1104,7 @@ public class DaoConfig { /** * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this - * setting is set to true (default is false) and the source + * setting is set to true (default is true) and the source * reference has an identifier populated, the identifier will be copied to the target * resource. *

@@ -1144,6 +1146,41 @@ public class DaoConfig { * } * } * + *

+ * Note that the default for this setting was previously false, and was changed to true + * in 5.4.0 with consideration to the following: + *

+ *
+	 * CP = Auto-Create Placeholder Reference Targets
+	 * PI = Populate Identifier in Auto-Created Placeholder Reference Targets
+	 *
+	 * CP | PI
+	 * -------
+	 *  F | F  <- PI=F is ignored
+	 *  F | T  <- PI=T is ignored
+	 *  T | F  <- resources may reference placeholder reference targets that are never updated : (
+	 *  T | T  <- placeholder reference targets can be updated : )
+	 * 
+ *

+ * Where CP=T and PI=F, the following could happen: + *

+ *
    + *
  1. + * Resource instance A is created with a reference to resource instance B. B is a placeholder reference target + * without an identifier. + *
  2. + *
  3. + * Resource instance C is conditionally created using a match URL. It is not matched to B although these + * resources represent the same entity. + *
  4. + *
  5. + * A continues to reference placeholder B, and does not reference populated C. + *
  6. + *
+ *

+ * There may be cases where configuring this setting to false would be appropriate; however, these are + * exceptional cases that should be opt-in. + *

* * @since 4.2.0 */ @@ -1153,7 +1190,7 @@ public class DaoConfig { /** * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this - * setting is set to true (default is false) and the source + * setting is set to true (default is true) and the source * reference has an identifier populated, the identifier will be copied to the target * resource. *

@@ -1195,6 +1232,41 @@ public class DaoConfig { * } * } * + *

+ * Note that the default for this setting was previously false, and was changed to true + * in 5.4.0 with consideration to the following: + *

+ *
+	 * CP = Auto-Create Placeholder Reference Targets
+	 * PI = Populate Identifier in Auto-Created Placeholder Reference Targets
+	 *
+	 * CP | PI
+	 * -------
+	 *  F | F  <- PI=F is ignored
+	 *  F | T  <- PI=T is ignored
+	 *  T | F  <- resources may reference placeholder reference targets that are never updated : (
+	 *  T | T  <- placeholder reference targets can be updated : )
+	 * 
+ *

+ * Where CP=T and PI=F, the following could happen: + *

+ *
    + *
  1. + * Resource instance A is created with a reference to resource instance B. B is a placeholder reference target + * without an identifier. + *
  2. + *
  3. + * Resource instance C is conditionally created using a match URL. It is not matched to B although these + * resources represent the same entity. + *
  4. + *
  5. + * A continues to reference placeholder B, and does not reference populated C. + *
  6. + *
+ *

+ * There may be cases where configuring this setting to false would be appropriate; however, these are + * exceptional cases that should be opt-in. + *

* * @since 4.2.0 */ diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCreatePlaceholdersR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCreatePlaceholdersR4Test.java index 820f5afe950..ae6a807fac1 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCreatePlaceholdersR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCreatePlaceholdersR4Test.java @@ -268,9 +268,10 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test { } @Test - public void testCreatePlaceholderWithMatchUrl_IdentifierNotCopiedByDefault() { + public void testCreatePlaceholderWithMatchUrl_IdentifierNotCopied() { myDaoConfig.setAutoCreatePlaceholderReferenceTargets(true); myDaoConfig.setAllowInlineMatchUrlReferences(true); + myDaoConfig.setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(false); Observation obsToCreate = new Observation(); obsToCreate.setStatus(ObservationStatus.FINAL); @@ -288,7 +289,7 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test { // FIXME: DM 2021-03-04 - This test fails; placeholder identifier isn't populated by default. @Test - public void testCreatePlaceholderWithMatchUrl_PopulateIdentifierSetToDefault_WithUpdateToTarget() { + public void testCreatePlaceholderWithMatchUrl_IdentifierCopiedByDefault_WithUpdateToTarget() { myDaoConfig.setAutoCreatePlaceholderReferenceTargets(true); myDaoConfig.setAllowInlineMatchUrlReferences(true); @@ -338,10 +339,9 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test { } @Test - public void testCreatePlaceholderWithMatchUrl_IdentifierCopied_NotPreExisting() { + public void testCreatePlaceholderWithMatchUrl_IdentifierCopiedByDefault_NotPreExisting() { myDaoConfig.setAutoCreatePlaceholderReferenceTargets(true); myDaoConfig.setAllowInlineMatchUrlReferences(true); - myDaoConfig.setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(true); Observation obsToCreate = new Observation(); obsToCreate.setStatus(ObservationStatus.FINAL); @@ -363,7 +363,6 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test { public void testCreatePlaceholderWithMatchUrl_IdentifierNotCopiedBecauseNoFieldMatches() { myDaoConfig.setAutoCreatePlaceholderReferenceTargets(true); myDaoConfig.setAllowInlineMatchUrlReferences(true); - myDaoConfig.setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(true); myDaoConfig.setBundleTypesAllowedForStorage(Sets.newHashSet("")); AuditEvent eventToCreate = new AuditEvent(); @@ -382,7 +381,6 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test { public void testCreatePlaceholderWithMatchUrl_PreExisting() { myDaoConfig.setAutoCreatePlaceholderReferenceTargets(true); myDaoConfig.setAllowInlineMatchUrlReferences(true); - myDaoConfig.setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(true); Patient patient = new Patient(); patient.setId("ABC");