Fix #55: Transaction in JPA should replace "cid:" IDs with server

assigned IDs
This commit is contained in:
James Agnew 2014-11-20 10:52:16 -05:00
parent 87b5ac2449
commit f632d119b4
6 changed files with 105 additions and 22 deletions

View File

@ -8,9 +8,7 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.resource.BaseConformance;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Organization;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
@ -120,8 +118,8 @@ public class GenericClientExample {
response = client.search()
.forResource(Patient.class)
.where(Patient.ADDRESS.matches().values("Toronto"))
.where(Patient.ADDRESS.matches().values("Ontario"))
.where(Patient.ADDRESS.matches().values("Canada"))
.and(Patient.ADDRESS.matches().values("Ontario"))
.and(Patient.ADDRESS.matches().values("Canada"))
.execute();
// END SNIPPET: searchAnd

View File

@ -1113,7 +1113,7 @@ public class FhirResourceDao<T extends IResource> extends BaseFhirDao implements
}
if (isBlank(ref.getChain())) {
Long targetPid = Long.valueOf(resourceId);
Long targetPid = translateForcedIdToPid(new IdDt(resourceId));
ourLog.info("Searching for resource link with target PID: {}", targetPid);
Predicate eq = builder.equal(from.get("myTargetResourcePid"), targetPid);

View File

@ -85,7 +85,11 @@ public class FhirSystemDao extends BaseFhirDao implements IFhirSystemDao {
if (entity == null) {
entity = toEntity(nextResource);
createForcedIdIfNeeded(entity, nextId);
if (!nextId.isEmpty() && nextId.getIdPart().startsWith("cid:")) {
ourLog.debug("Resource in transaction has ID[{}], will replace with server assigned ID", nextId.getIdPart());
} else {
createForcedIdIfNeeded(entity, nextId);
}
myEntityManager.persist(entity);
if (entity.getForcedId() != null) {
myEntityManager.persist(entity.getForcedId());

View File

@ -630,7 +630,7 @@ public class FhirResourceDaoTest {
patient.addName().addFamily("Tester").addGiven("testHistoryByForcedId");
patient.setId("Patient/testHistoryByForcedId");
idv1 = ourPatientDao.create(patient).getId();
patient.addName().addFamily("Tester").addGiven("testHistoryByForcedIdName2");
idv2 = ourPatientDao.update(patient, idv1.toUnqualifiedVersionless()).getId();
}
@ -642,8 +642,6 @@ public class FhirResourceDaoTest {
assertEquals("Patient/testHistoryByForcedId/_history/1", patients.get(1).getId().toUnqualified().getValue());
}
@Test
public void testSearchByIdParam() {
IdDt id1;
@ -860,6 +858,57 @@ public class FhirResourceDaoTest {
}
@Test
public void testSearchResourceLinkWithTextLogicalId() {
Patient patient = new Patient();
patient.setId("testSearchResourceLinkWithTextLogicalId01");
patient.addIdentifier("urn:system", "testSearchResourceLinkWithTextLogicalIdXX");
patient.addIdentifier("urn:system", "testSearchResourceLinkWithTextLogicalId01");
IdDt patientId01 = ourPatientDao.create(patient).getId();
Patient patient02 = new Patient();
patient02.setId("testSearchResourceLinkWithTextLogicalId02");
patient02.addIdentifier("urn:system", "testSearchResourceLinkWithTextLogicalIdXX");
patient02.addIdentifier("urn:system", "testSearchResourceLinkWithTextLogicalId02");
IdDt patientId02 = ourPatientDao.create(patient02).getId();
Observation obs01 = new Observation();
obs01.setApplies(new DateTimeDt(new Date()));
obs01.setSubject(new ResourceReferenceDt(patientId01));
IdDt obsId01 = ourObservationDao.create(obs01).getId();
Observation obs02 = new Observation();
obs02.setApplies(new DateTimeDt(new Date()));
obs02.setSubject(new ResourceReferenceDt(patientId02));
IdDt obsId02 = ourObservationDao.create(obs02).getId();
// Create another type, that shouldn't be returned
DiagnosticReport dr01 = new DiagnosticReport();
dr01.setSubject(new ResourceReferenceDt(patientId01));
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
List<Observation> result = toList(ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("testSearchResourceLinkWithTextLogicalId01")));
assertEquals(1, result.size());
assertEquals(obsId01.getIdPart(), result.get(0).getId().getIdPart());
try {
ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("testSearchResourceLinkWithTextLogicalId99"));
fail();
} catch (ResourceNotFoundException e) {
// good
}
/*
* TODO: it's kind of weird that we throw a 404 for textual IDs that don't exist, but just return an empty list for numeric IDs that don't exist
*/
result = toList(ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("999999999999999")));
assertEquals(0, result.size());
}
@Test
public void testSearchResourceLinkWithChainWithMultipleTypes() {
Patient patient = new Patient();
@ -1222,9 +1271,9 @@ public class FhirResourceDaoTest {
ourPatientDao.addTag(patientId, "http://foo", "Cat", "Kittens");
ourPatientDao.addTag(patientId, "http://foo", "Cow", "Calves");
retrieved = ourPatientDao.read(patientId);
published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
retrieved = ourPatientDao.read(patientId);
published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
assertEquals(3, published.size());
assertEquals("Dog", published.get(0).getTerm());
assertEquals("Puppies", published.get(0).getLabel());
@ -1235,8 +1284,7 @@ public class FhirResourceDaoTest {
assertEquals("Cow", published.get(2).getTerm());
assertEquals("Calves", published.get(2).getLabel());
assertEquals("http://foo", published.get(2).getScheme());
}
@Test
@ -1412,14 +1460,14 @@ public class FhirResourceDaoTest {
p2.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId02");
IdDt p2id = ourPatientDao.create(p2).getId();
long p1longId = p2id.getIdPartAsLong() - 1;
try {
ourPatientDao.read(new IdDt("Patient/" + p1longId));
fail();
} catch (ResourceNotFoundException e) {
// good
}
try {
ourPatientDao.update(p1, new IdDt("Patient/" + p1longId));
fail();
@ -1429,7 +1477,6 @@ public class FhirResourceDaoTest {
}
@Test
public void testReadForcedIdVersionHistory() throws InterruptedException {
Patient p1 = new Patient();
@ -1441,18 +1488,17 @@ public class FhirResourceDaoTest {
p1.addIdentifier("urn:system", "testReadVorcedIdVersionHistory02");
IdDt p1idv2 = ourPatientDao.update(p1, p1id).getId();
assertEquals("testReadVorcedIdVersionHistory", p1idv2.getIdPart());
assertNotEquals(p1id.getValue(), p1idv2.getValue());
assertNotEquals(p1id.getValue(), p1idv2.getValue());
Patient v1 = ourPatientDao.read(p1id);
assertEquals(1, v1.getIdentifier().size());
Patient v2 = ourPatientDao.read(p1idv2);
assertEquals(2, v2.getIdentifier().size());
}
@SuppressWarnings("unchecked")
private <T extends IResource> List<T> toList(IBundleProvider theSearch) {
return (List<T>) theSearch.getResources(0, theSearch.size());

View File

@ -212,6 +212,41 @@ public class FhirSystemDaoTest {
}
/**
* Issue #55
*/
@Test
public void testTransactionWithCidIds() throws Exception {
List<IResource> res = new ArrayList<IResource>();
Patient p1 = new Patient();
p1.setId("cid:patient1");
p1.addIdentifier("system", "testTransactionWithCidIds01");
res.add(p1);
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.getIdentifier().setSystem("system").setValue("testTransactionWithCidIds02");
o1.setSubject(new ResourceReferenceDt("Patient/cid:patient1"));
res.add(o1);
Observation o2 = new Observation();
o2.setId("cid:observation1");
o2.getIdentifier().setSystem("system").setValue("testTransactionWithCidIds03");
o2.setSubject(new ResourceReferenceDt("Patient/cid:patient1"));
res.add(o2);
ourSystemDao.transaction(res);
assertTrue(p1.getId().getValue(), p1.getId().getIdPart().matches("^[0-9]+$"));
assertTrue(o1.getId().getValue(), o1.getId().getIdPart().matches("^[0-9]+$"));
assertTrue(o2.getId().getValue(), o2.getId().getIdPart().matches("^[0-9]+$"));
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
}
@Test
public void testTransactionFromBundle() throws Exception {

View File

@ -111,7 +111,7 @@
This leads to a URL resembling <code>?address=Toronto&amp;address=Ontario&amp;address=Canada</code>
</p>
<macro name="snippet">
<param name="id" value="searchOr" />
<param name="id" value="searchAnd" />
<param name="file"
value="examples/src/main/java/example/GenericClientExample.java" />
</macro>