diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HapiFlywayMigrateDatabaseCommandTest.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HapiFlywayMigrateDatabaseCommandTest.java
index 7da2c97911b..0ed53b49fdd 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HapiFlywayMigrateDatabaseCommandTest.java
+++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HapiFlywayMigrateDatabaseCommandTest.java
@@ -81,7 +81,7 @@ public class HapiFlywayMigrateDatabaseCommandTest {
@Test
public void testMigrateFrom340_NoFlyway() throws IOException, SQLException {
- File location = getLocation("migrator_h2_test_340_current");
+ File location = getLocation("migrator_h2_test_340_current_noflyway");
String url = "jdbc:h2:" + location.getAbsolutePath() + ";create=true";
DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.H2_EMBEDDED.newConnectionProperties(url, "", "");
diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml
index 05b8bc61c91..433d5389d57 100644
--- a/hapi-fhir-docs/pom.xml
+++ b/hapi-fhir-docs/pom.xml
@@ -82,11 +82,6 @@
jdom2
2.0.6
-
- org.slf4j
- slf4j-simple
- 1.7.28
-
javax.servlet
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteConflictList.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteConflictList.java
index 3ea747d7b17..24a44b7fccd 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteConflictList.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteConflictList.java
@@ -24,12 +24,17 @@ import ca.uhn.fhir.jpa.util.DeleteConflict;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IIdType;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import java.util.function.Predicate;
public class DeleteConflictList implements Iterable {
private final List myList = new ArrayList<>();
private final Set myResourceIdsMarkedForDeletion;
+ private int myRemoveModCount;
/**
* Constructor
@@ -69,11 +74,38 @@ public class DeleteConflictList implements Iterable {
@Override
public Iterator iterator() {
- return myList.iterator();
+ // Note that handlers may add items to this list, so we're using a special iterator
+ // that is ok with this. Only removals from the list should trigger a concurrent modification
+ // issue
+ return new Iterator() {
+
+ private final int myOriginalRemoveModCont = myRemoveModCount;
+ private int myNextIndex = 0;
+
+ @Override
+ public boolean hasNext() {
+ checkForCoModification();
+ return myNextIndex < myList.size();
+ }
+
+ @Override
+ public DeleteConflict next() {
+ checkForCoModification();
+ return myList.get(myNextIndex++);
+ }
+
+ private void checkForCoModification() {
+ Validate.isTrue(myOriginalRemoveModCont == myRemoveModCount);
+ }
+ };
}
public boolean removeIf(Predicate theFilter) {
- return myList.removeIf(theFilter);
+ boolean retVal = myList.removeIf(theFilter);
+ if (retVal) {
+ myRemoveModCount++;
+ }
+ return retVal;
}
public void addAll(DeleteConflictList theNewConflicts) {
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CascadingDeleteInterceptorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CascadingDeleteInterceptorR4Test.java
index 55c6bbfac2c..0e447601bb3 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CascadingDeleteInterceptorR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CascadingDeleteInterceptorR4Test.java
@@ -64,6 +64,10 @@ public class CascadingDeleteInterceptorR4Test extends BaseResourceProviderR4Test
e.setSubject(new Reference(myPatientId));
myEncounterId = ourClient.create().resource(e).execute().getId().toUnqualifiedVersionless();
+ CarePlan cp = new CarePlan();
+ cp.setEncounter(new Reference(myEncounterId));
+ ourClient.create().resource(cp).execute();
+
Observation o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSubject( new Reference(myPatientId));
diff --git a/hapi-fhir-jpaserver-migrate/pom.xml b/hapi-fhir-jpaserver-migrate/pom.xml
index 8c12ac366c7..345bf13d5ee 100644
--- a/hapi-fhir-jpaserver-migrate/pom.xml
+++ b/hapi-fhir-jpaserver-migrate/pom.xml
@@ -101,6 +101,22 @@
+
+ org.jacoco
+ jacoco-maven-plugin
+
+ true
+
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+
+
org.apache.maven.plugins
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java
index 4d7fb50aa40..75e083894d9 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.migrate;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Migration
+ * %%
+ * Copyright (C) 2014 - 2019 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
import org.flywaydb.core.api.MigrationInfoService;
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BruteForceMigrator.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BruteForceMigrator.java
index 6853aafd13c..d40871f226c 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BruteForceMigrator.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BruteForceMigrator.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.migrate;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Migration
+ * %%
+ * Copyright (C) 2014 - 2019 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.flywaydb.core.api.MigrationInfoService;
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d9c96b0bf4e..e261d7632cb 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,10 @@
ValueSet Precalculation sometimes failed on Oracle DBs due to an invalid SQL function. This
has been corrected.
+
+ A ConcurrentModificationException was sometimes thrown when performing a cascading delete.
+ This has been corrected.
+