JPA server transactions sometimes created an incorrect resource reference if a resource being saved contained references that had a display value but not an actual reference. Thanks to David Hay for reporting!

This commit is contained in:
jamesagnew 2016-04-29 09:21:12 -04:00
parent 649c6807cb
commit 2bc1950bc1
8 changed files with 299 additions and 77 deletions

View File

@ -42,6 +42,10 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetai
public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>implements IFhirResourceDaoPatient<Patient> {
public FhirResourceDaoPatientDstu2() {
super();
}
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {

View File

@ -460,6 +460,9 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
List<BaseResourceReferenceDt> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : allRefs) {
IdDt nextId = nextRef.getReference();
if (!nextId.hasIdPart()) {
continue;
}
if (idSubstitutions.containsKey(nextId)) {
IdDt newId = idSubstitutions.get(nextId);
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);

View File

@ -470,6 +470,9 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
List<IBaseReference> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, IBaseReference.class);
for (IBaseReference nextRef : allRefs) {
IIdType nextId = nextRef.getReferenceElement();
if (!nextId.hasIdPart()) {
continue;
}
if (idSubstitutions.containsKey(nextId)) {
IdType newId = idSubstitutions.get(nextId);
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);

View File

@ -18,7 +18,6 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
@ -41,6 +40,7 @@ import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Appointment;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.ConceptMap;
import ca.uhn.fhir.model.dstu2.resource.Device;
@ -87,6 +87,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
@Qualifier("myConceptMapDaoDstu2")
protected IFhirResourceDao<ConceptMap> myConceptMapDao;
@Autowired
@Qualifier("myAppointmentDaoDstu2")
protected IFhirResourceDao<Appointment> myAppointmentDao;
@Autowired
@Qualifier("myBundleDaoDstu2")
protected IFhirResourceDao<Bundle> myBundleDao;
@Autowired

View File

@ -43,6 +43,7 @@ import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.Appointment;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryRequest;
@ -66,19 +67,12 @@ import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.TestUtil;
public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2Test.class);
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@Test
public void testReindexing() {
Patient p = new Patient();
@ -288,6 +282,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
@Test
public void testTransactionCreateMatchUrlWithOneMatch() {
String methodName = "testTransactionCreateMatchUrlWithOneMatch";
@ -929,6 +924,25 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdDt patientPlaceholderId) {
Bundle req = new Bundle();
req.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?identifier=" + methodName);
Observation obs = new Observation();
obs.getSubject().setReference(patientPlaceholderId);
obs.addIdentifier().setValue(methodName);
obs.getCode().setText(methodName + pass);
req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Observation?identifier=" + methodName);
Patient pat = new Patient();
pat.addIdentifier().setValue(methodName);
pat.addName().addFamily(methodName + pass);
req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
req.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=" + methodName);
return req;
}
private void testTransactionOrderingValidateResponse(int pass, Bundle resp) {
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(4, resp.getEntry().size());
@ -957,25 +971,6 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
assertThat(respGetBundle.getLink("self").getUrl(), endsWith("/Patient?identifier=testTransactionOrdering"));
}
private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdDt patientPlaceholderId) {
Bundle req = new Bundle();
req.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?identifier=" + methodName);
Observation obs = new Observation();
obs.getSubject().setReference(patientPlaceholderId);
obs.addIdentifier().setValue(methodName);
obs.getCode().setText(methodName + pass);
req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Observation?identifier=" + methodName);
Patient pat = new Patient();
pat.addIdentifier().setValue(methodName);
pat.addName().addFamily(methodName + pass);
req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
req.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=" + methodName);
return req;
}
@Test
public void testTransactionReadAndSearch() {
String methodName = "testTransactionReadAndSearch";
@ -1308,6 +1303,87 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
/**
* From a message from David Hay
*/
@Test
public void testTransactionWithAppointments() {
Patient p = new Patient();
p.addName().addFamily("family");
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
//@formatter:on
String input = "{\n" +
" \"resourceType\": \"Bundle\",\n" +
" \"type\": \"transaction\",\n" +
" \"entry\": [\n" +
" {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Appointment\",\n" +
" \"status\": \"pending\",\n" +
" \"type\": {\"text\": \"Cardiology\"},\n" +
" \"description\": \"Investigate Angina\",\n" +
" \"start\": \"2016-04-30T18:48:29+12:00\",\n" +
" \"end\": \"2016-04-30T19:03:29+12:00\",\n" +
" \"minutesDuration\": 15,\n" +
" \"participant\": [\n" +
" {\n" +
" \"actor\": {\"display\": \"Clarence cardiology clinic\"},\n" +
" \"status\": \"accepted\"\n" +
" },\n" +
" {\n" +
" \"actor\": {\"reference\": \"Patient/" + id.getIdPart() + "\"},\n" +
" \"status\": \"accepted\"\n" +
" }\n" +
" ],\n" +
" \"text\": {\n" +
" \"status\": \"generated\",\n" +
" \"div\": \"<div><div>Investigate Angina<\\/div><div>Clarence cardiology clinic<\\/div><\\/div>\"\n" +
" }\n" +
" },\n" +
" \"request\": {\n" +
" \"method\": \"POST\",\n" +
" \"url\": \"Appointment\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Appointment\",\n" +
" \"status\": \"pending\",\n" +
" \"type\": {\"text\": \"GP Visit\"},\n" +
" \"description\": \"Routine checkup\",\n" +
" \"start\": \"2016-05-03T18:48:29+12:00\",\n" +
" \"end\": \"2016-05-03T19:03:29+12:00\",\n" +
" \"minutesDuration\": 15,\n" +
" \"participant\": [\n" +
" {\n" +
" \"actor\": {\"display\": \"Dr Dave\"},\n" +
" \"status\": \"accepted\"\n" +
" },\n" +
" {\n" +
" \"actor\": {\"reference\": \"Patient/" + id.getIdPart() + "\"},\n" +
" \"status\": \"accepted\"\n" +
" }\n" +
" ],\n" +
" \"text\": {\n" +
" \"status\": \"generated\",\n" +
" \"div\": \"<div><div>Routine checkup<\\/div><div>Dr Dave<\\/div><\\/div>\"\n" +
" }\n" +
" },\n" +
" \"request\": {\n" +
" \"method\": \"POST\",\n" +
" \"url\": \"Appointment\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
//@formatter:on
Bundle inputBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, input);
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
}
@Test
public void testTransactionWithInvalidType() {
Bundle request = new Bundle();
@ -1324,6 +1400,65 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
@Test
public void testTransactionWithNullReference() {
Patient p = new Patient();
p.addName().addFamily("family");
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
Bundle inputBundle = new Bundle();
//@formatter:off
Patient app0 = new Patient();
app0.addName().addFamily("NEW PATIENT");
String placeholderId0 = IdDt.newRandomUuid().getValue();
inputBundle
.addEntry()
.setResource(app0)
.setFullUrl(placeholderId0)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Patient");
//@formatter:on
//@formatter:off
Appointment app1 = new Appointment();
app1.addParticipant().getActor().setReference(id);
inputBundle
.addEntry()
.setResource(app1)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Appointment");
//@formatter:on
//@formatter:off
Appointment app2 = new Appointment();
app2.addParticipant().getActor().setDisplay("NO REF");
app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0);
inputBundle
.addEntry()
.setResource(app2)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Appointment");
//@formatter:on
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
assertEquals(3, outputBundle.getEntry().size());
IdDt id0 = new IdDt(outputBundle.getEntry().get(0).getResponse().getLocation());
IdDt id1 = new IdDt(outputBundle.getEntry().get(1).getResponse().getLocation());
IdDt id2 = new IdDt(outputBundle.getEntry().get(2).getResponse().getLocation());
app2 = myAppointmentDao.read(id2, mySrd);
assertEquals("NO REF", app2.getParticipant().get(0).getActor().getDisplay().getValue());
assertEquals(null, app2.getParticipant().get(0).getActor().getReference().getValue());
assertEquals("YES REF", app2.getParticipant().get(1).getActor().getDisplay().getValue());
assertEquals(id0.toUnqualifiedVersionless().getValue(), app2.getParticipant().get(1).getActor().getReference().getValue());
}
@Test
public void testTransactionWithReferenceToCreateIfNoneExist() {
Bundle bundle = new Bundle();
@ -1377,6 +1512,46 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
assertNotEquals(medOrderId1, medOrderId2);
}
@Test
public void testTransactionWithRelativeOidIds() throws Exception {
Bundle res = new Bundle();
res.setType(BundleTypeEnum.TRANSACTION);
Patient p1 = new Patient();
p1.setId("urn:oid:0.1.2.3");
p1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds01");
res.addEntry().setResource(p1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
o1.setSubject(new ResourceReferenceDt("urn:oid:0.1.2.3"));
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
Observation o2 = new Observation();
o2.setId("cid:observation2");
o2.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds03");
o2.setSubject(new ResourceReferenceDt("urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
Bundle resp = mySystemDao.transaction(mySrd, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
assertEquals(3, resp.getEntry().size());
assertTrue(resp.getEntry().get(0).getResponse().getLocation(), new IdDt(resp.getEntry().get(0).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdDt(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdDt(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
o1 = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()), mySrd);
o2 = myObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()), mySrd);
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
}
//
//
// /**
@ -1479,46 +1654,6 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
//
// }
@Test
public void testTransactionWithRelativeOidIds() throws Exception {
Bundle res = new Bundle();
res.setType(BundleTypeEnum.TRANSACTION);
Patient p1 = new Patient();
p1.setId("urn:oid:0.1.2.3");
p1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds01");
res.addEntry().setResource(p1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
o1.setSubject(new ResourceReferenceDt("urn:oid:0.1.2.3"));
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
Observation o2 = new Observation();
o2.setId("cid:observation2");
o2.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds03");
o2.setSubject(new ResourceReferenceDt("urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
Bundle resp = mySystemDao.transaction(mySrd, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
assertEquals(3, resp.getEntry().size());
assertTrue(resp.getEntry().get(0).getResponse().getLocation(), new IdDt(resp.getEntry().get(0).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdDt(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdDt(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
o1 = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()), mySrd);
o2 = myObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()), mySrd);
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
}
/**
* This is not the correct way to do it, but we'll allow it to be lenient
*/
@ -1562,4 +1697,9 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -12,6 +12,7 @@ import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.model.Appointment;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept;
@ -90,12 +91,15 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Autowired
@Qualifier("myCodeSystemDaoDstu3")
protected IFhirResourceDao<CodeSystem> myCodeSystemDao;
@Qualifier("myAppointmentDaoDstu3")
protected IFhirResourceDao<Appointment> myAppointmentDao;
@Autowired
@Qualifier("myBundleDaoDstu3")
protected IFhirResourceDao<Bundle> myBundleDao;
@Autowired
@Qualifier("myCodeSystemDaoDstu3")
protected IFhirResourceDao<CodeSystem> myCodeSystemDao;
@Autowired
@Qualifier("myConceptMapDaoDstu3")
protected IFhirResourceDao<ConceptMap> myConceptMapDao;
@Autowired
@ -139,6 +143,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Autowired
@Qualifier("myNamingSystemDaoDstu3")
protected IFhirResourceDao<NamingSystem> myNamingSystemDao;
@Autowired
@Qualifier("myObservationDaoDstu3")
protected IFhirResourceDao<Observation> myObservationDao;
@ -146,7 +151,6 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Autowired
@Qualifier("myOrganizationDaoDstu3")
protected IFhirResourceDao<Organization> myOrganizationDao;
@Autowired
@Qualifier("myPatientDaoDstu3")
protected IFhirResourceDaoPatient<Patient> myPatientDao;

View File

@ -22,6 +22,7 @@ import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.Appointment;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryRequestComponent;
@ -58,6 +59,7 @@ import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IBundleProvider;
@ -77,6 +79,64 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@Test
public void testTransactionWithNullReference() {
Patient p = new Patient();
p.addName().addFamily("family");
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
Bundle inputBundle = new Bundle();
//@formatter:off
Patient app0 = new Patient();
app0.addName().addFamily("NEW PATIENT");
String placeholderId0 = IdDt.newRandomUuid().getValue();
inputBundle
.addEntry()
.setResource(app0)
.setFullUrl(placeholderId0)
.getRequest()
.setMethod(HTTPVerb.POST)
.setUrl("Patient");
//@formatter:on
//@formatter:off
Appointment app1 = new Appointment();
app1.addParticipant().getActor().setReference(id.getValue());
inputBundle
.addEntry()
.setResource(app1)
.getRequest()
.setMethod(HTTPVerb.POST)
.setUrl("Appointment");
//@formatter:on
//@formatter:off
Appointment app2 = new Appointment();
app2.addParticipant().getActor().setDisplay("NO REF");
app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0);
inputBundle
.addEntry()
.setResource(app2)
.getRequest()
.setMethod(HTTPVerb.POST)
.setUrl("Appointment");
//@formatter:on
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
assertEquals(3, outputBundle.getEntry().size());
IdDt id0 = new IdDt(outputBundle.getEntry().get(0).getResponse().getLocation());
IdDt id2 = new IdDt(outputBundle.getEntry().get(2).getResponse().getLocation());
app2 = myAppointmentDao.read(id2, mySrd);
assertEquals("NO REF", app2.getParticipant().get(0).getActor().getDisplay());
assertEquals(null, app2.getParticipant().get(0).getActor().getReference());
assertEquals("YES REF", app2.getParticipant().get(1).getActor().getDisplay());
assertEquals(id0.toUnqualifiedVersionless().getValue(), app2.getParticipant().get(1).getActor().getReference());
}
@Test
public void testReindexing() {

View File

@ -51,6 +51,11 @@
Note that existing databases will need to modify index "IDX_FORCEDID" as
it is no longer unique, and perform a reindexing pass.
</action>
<action type="fix">
JPA server transactions sometimes created an incorrect resource reference
if a resource being saved contained references that had a display value but
not an actual reference. Thanks to David Hay for reporting!
</action>
</release>
<release version="1.5" date="2016-04-20">
<action type="fix" issue="339">