Fix expunge issue when no tags present (#1671)

* Fix expunge issue when no tags present

* Add changelog

* Try to clean up POMs that are failing CI

* Rework dependencies

* Roll back change that did not work
This commit is contained in:
James Agnew 2020-01-15 14:47:22 +08:00 committed by GitHub
parent 0385c25aa3
commit 201ec34db4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 173 additions and 136 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 1671
title: When performing the $expunge operation in the JPA server, the operation sometimes failed if a
resource being expunged had historical versions that did not contain any tags. This has been corrected.

View File

@ -31,7 +31,7 @@ import java.util.List;
public interface IResourceHistoryTagDao extends JpaRepository<ResourceHistoryTag, Long> { public interface IResourceHistoryTagDao extends JpaRepository<ResourceHistoryTag, Long> {
@Modifying @Modifying
@Query("DELETE FROM ResourceHistoryTag t WHERE t.myId IN :pids") @Query("DELETE FROM ResourceHistoryTag t WHERE t.myResourceHistoryPid = :historyPid")
void deleteByPid(@Param("pids") List<Long> thePids); void deleteByPid(@Param("historyPid") Long theResourceHistoryTablePid);
} }

View File

@ -37,5 +37,5 @@ public interface IResourceTagDao extends JpaRepository<ResourceTag, Long> {
Collection<ResourceTag> findByResourceIds(@Param("pids") Collection<Long> pids); Collection<ResourceTag> findByResourceIds(@Param("pids") Collection<Long> pids);
@Modifying @Modifying
@Query("delete from ResourceTag t WHERE t.myResourceId = :resid") @Query("delete from ResourceTag t WHERE t.myResourceId = :resId")
void deleteByResourceId(@Param("resid") Long theResourcePid);} void deleteByResourceId(@Param("resId") Long theResourcePid);}

View File

@ -50,7 +50,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Service @Service
class ResourceExpungeService implements IResourceExpungeService { class ResourceExpungeService implements IResourceExpungeService {
@ -151,7 +150,7 @@ class ResourceExpungeService implements IResourceExpungeService {
myResourceHistoryProvenanceTableDao.deleteByPid(version.getProvenance().getId()); myResourceHistoryProvenanceTableDao.deleteByPid(version.getProvenance().getId());
} }
myResourceHistoryTagDao.deleteByPid(version.getTags().stream().map(t->t.getId()).collect(Collectors.toList())); myResourceHistoryTagDao.deleteByPid(version.getId());
myResourceHistoryTableDao.deleteByPid(version.getId()); myResourceHistoryTableDao.deleteByPid(version.getId());
theRemainingCount.decrementAndGet(); theRemainingCount.decrementAndGet();

View File

@ -171,6 +171,34 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
@Test @Test
public void testExpungeAllVersionsDeletesRow() { public void testExpungeAllVersionsDeletesRow() {
// Create then delete
Patient p = new Patient();
p.setId("TEST");
p.setActive(true);
p.addName().setFamily("FOO");
myPatientDao.update(p);
p.setActive(false);
myPatientDao.update(p);
myPatientDao.delete(new IdType("Patient/TEST"));
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true), null);
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
}
@Test
public void testExpungeAllVersionsWithTagsDeletesRow() {
// Create then delete // Create then delete
Patient p = new Patient(); Patient p = new Patient();
p.setId("TEST"); p.setId("TEST");
@ -178,6 +206,10 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
p.setActive(true); p.setActive(true);
p.addName().setFamily("FOO"); p.addName().setFamily("FOO");
myPatientDao.update(p).getId(); myPatientDao.update(p).getId();
p.setActive(false);
myPatientDao.update(p);
myPatientDao.delete(new IdType("Patient/TEST")); myPatientDao.delete(new IdType("Patient/TEST"));
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty()))); runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));

View File

@ -42,6 +42,9 @@ public class ResourceHistoryTag extends BaseTag implements Serializable {
@JoinColumn(name="RES_VER_PID", referencedColumnName="PID", nullable=false, foreignKey=@ForeignKey(name="FK_HISTORYTAG_HISTORY")) @JoinColumn(name="RES_VER_PID", referencedColumnName="PID", nullable=false, foreignKey=@ForeignKey(name="FK_HISTORYTAG_HISTORY"))
private ResourceHistoryTable myResourceHistory; private ResourceHistoryTable myResourceHistory;
@Column(name="RES_VER_PID", insertable = false, updatable = false, nullable = false)
private Long myResourceHistoryPid;
@Column(name = "RES_TYPE", length = ResourceTable.RESTYPE_LEN, nullable=false) @Column(name = "RES_TYPE", length = ResourceTable.RESTYPE_LEN, nullable=false)
private String myResourceType; private String myResourceType;

View File

@ -113,7 +113,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
<!--
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
@ -126,7 +125,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
-->
<build> <build>
<plugins> <plugins>

View File

@ -1,64 +1,64 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>4.2.0-SNAPSHOT</version> <version>4.2.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<dependencies> <dependencies>
<!-- Compile --> <!-- Compile -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-starter</artifactId> <artifactId>hapi-fhir-spring-boot-starter</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu3</artifactId> <artifactId>hapi-fhir-structures-dstu3</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-client</artifactId> <artifactId>hapi-fhir-client</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- Optional --> <!-- Optional -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId> <artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -1,64 +1,64 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>4.2.0-SNAPSHOT</version> <version>4.2.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<dependencies> <dependencies>
<!-- Compile --> <!-- Compile -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-starter</artifactId> <artifactId>hapi-fhir-spring-boot-starter</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu3</artifactId> <artifactId>hapi-fhir-structures-dstu3</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-client-okhttp</artifactId> <artifactId>hapi-fhir-client-okhttp</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- Optional --> <!-- Optional -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId> <artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>