From ce253bed7074f81cf8a127af151122cc6c73d051 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Sat, 12 Mar 2016 13:23:55 -0500 Subject: [PATCH] Properly deserialize bound codes --- .../uhn/fhir/model/primitive/BoundCodeDt.java | 21 ++- .../instance/model/api/IBaseEnumFactory.java | 4 +- .../test/java/ca/uhn/fhir/jpa/config/Tmp.java | 56 ------ .../composite/BoundCodeableConceptDt.java | 2 - ....java => ModelSerializationDstu2Test.java} | 85 ++++++--- .../org/hl7/fhir/dstu3/model/Enumeration.java | 32 +++- .../hl7/fhir/dstu3/model/PrimitiveType.java | 174 ++++++++++-------- .../model/ModelSerializationDstu3Test.java | 82 +++++++++ src/changes/changes.xml | 8 + 9 files changed, 292 insertions(+), 172 deletions(-) delete mode 100644 hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/Tmp.java rename hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/{ModelSerializationTest.java => ModelSerializationDstu2Test.java} (60%) create mode 100644 hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/model/ModelSerializationDstu3Test.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BoundCodeDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BoundCodeDt.java index 6af5e6c84c8..b64fecee753 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BoundCodeDt.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BoundCodeDt.java @@ -1,5 +1,9 @@ package ca.uhn.fhir.model.primitive; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + /* * #%L * HAPI FHIR - Core Library @@ -42,7 +46,7 @@ public class BoundCodeDt> extends CodeDt { Validate.notNull(theBinder, "theBinder must not be null"); myBinder = theBinder; } - + public BoundCodeDt(IValueSetEnumBinder theBinder, T theValue) { Validate.notNull(theBinder, "theBinder must not be null"); myBinder = theBinder; @@ -52,7 +56,7 @@ public class BoundCodeDt> extends CodeDt { public IValueSetEnumBinder getBinder() { return myBinder; } - + public T getValueAsEnum() { Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeDt() should not be called!"); T retVal = myBinder.fromCodeString(getValue()); @@ -62,6 +66,13 @@ public class BoundCodeDt> extends CodeDt { return retVal; } + @SuppressWarnings("unchecked") + @Override + public void readExternal(ObjectInput theIn) throws IOException, ClassNotFoundException { + super.readExternal(theIn); + myBinder = (IValueSetEnumBinder) theIn.readObject(); + } + public void setValueAsEnum(T theValue) { Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeDt() should not be called!"); if (theValue==null) { @@ -70,4 +81,10 @@ public class BoundCodeDt> extends CodeDt { setValue(myBinder.toCodeString(theValue)); } } + + @Override + public void writeExternal(ObjectOutput theOut) throws IOException { + super.writeExternal(theOut); + theOut.writeObject(myBinder); + } } diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumFactory.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumFactory.java index 1ee82a06eb8..dc3daf1e358 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumFactory.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumFactory.java @@ -1,5 +1,7 @@ package org.hl7.fhir.instance.model.api; +import java.io.Serializable; + /* * #%L * HAPI FHIR - Core Library @@ -20,7 +22,7 @@ package org.hl7.fhir.instance.model.api; * #L% */ -public interface IBaseEnumFactory> { +public interface IBaseEnumFactory> extends Serializable { /** * Read an enumeration value from the string that represents it on the XML or JSON diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/Tmp.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/Tmp.java deleted file mode 100644 index 04bd323c8c3..00000000000 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/Tmp.java +++ /dev/null @@ -1,56 +0,0 @@ -package ca.uhn.fhir.jpa.config; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.dstu2.resource.Bundle; -import ca.uhn.fhir.model.dstu2.resource.Organization; -import ca.uhn.fhir.model.dstu2.resource.Patient; -import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum; -import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum; -import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.rest.client.IGenericClient; -import ca.uhn.fhir.rest.client.ServerValidationModeEnum; - -public class Tmp { - - public static void main(String[] args) { - - FhirContext ctx = FhirContext.forDstu2(); - ctx.getRestfulClientFactory().setSocketTimeout(200000); - ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); - IGenericClient client = ctx.newRestfulGenericClient("http://localhost:8080/hapi-fhir-jpaserver-example/baseDstu2"); - - Bundle b = new Bundle(); - b.setType(BundleTypeEnum.TRANSACTION); - int resCount = 20; - for (int i = 0; i < (resCount / 2); i++) { - Organization org = new Organization(); - org.setId(IdDt.newRandomUuid()); - org.setName("Random Org " + i); - org.addAddress().addLine("Random Org Line 1"); - org.addIdentifier().setSystem("urn:foo").setValue("some_system" + i); - b.addEntry().setResource(org).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Organization"); - - Patient patient = new Patient(); - patient.setId(IdDt.newRandomUuid()); - patient.addName().addFamily("Family" + i).addGiven("Gigven " + i); - patient.addAddress().addLine("Random Patient Line 1"); - patient.addIdentifier().setSystem("urn:bar").setValue("some_system" + i); - b.addEntry().setResource(patient).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient"); - } - - int total = 0; - long start = System.currentTimeMillis(); - for (int i = 0; i < 300; i++) { - client.transaction().withBundle(b).execute(); - ourLog.info("" + i); - total += resCount; - } - - long delay = System.currentTimeMillis() - start; - ourLog.info("Wrote {} resources at {}ms / res", total, delay / total); - - //sync 13:57:14.683 [main] INFO ca.uhn.fhir.jpa.config.Tmp - Wrote 6000 resources at 7ms / res - } -private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Tmp.class); - -} diff --git a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/composite/BoundCodeableConceptDt.java b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/composite/BoundCodeableConceptDt.java index db3fb862b07..6c985990277 100644 --- a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/composite/BoundCodeableConceptDt.java +++ b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/composite/BoundCodeableConceptDt.java @@ -31,8 +31,6 @@ import org.apache.commons.lang3.Validate; import ca.uhn.fhir.model.api.IBoundCodeableConcept; import ca.uhn.fhir.model.api.IValueSetEnumBinder; import ca.uhn.fhir.model.api.annotation.DatatypeDef; -import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt; -import ca.uhn.fhir.model.dstu2.composite.CodingDt; @DatatypeDef(name = "CodeableConcept", isSpecialization = true) public class BoundCodeableConceptDt> extends CodeableConceptDt implements IBoundCodeableConcept { diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/ModelSerializationTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/ModelSerializationDstu2Test.java similarity index 60% rename from hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/ModelSerializationTest.java rename to hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/ModelSerializationDstu2Test.java index 16534773a10..944d638053f 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/ModelSerializationTest.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/model/dstu2/ModelSerializationDstu2Test.java @@ -3,7 +3,6 @@ package ca.uhn.fhir.model.dstu2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.io.Serializable; import java.util.Date; import org.apache.commons.io.IOUtils; @@ -15,18 +14,71 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.dstu2.composite.AddressDt; import ca.uhn.fhir.model.dstu2.composite.HumanNameDt; +import ca.uhn.fhir.model.dstu2.composite.IdentifierDt; import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Patient; +import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum; +import ca.uhn.fhir.model.dstu2.valueset.IdentifierTypeCodesEnum; import ca.uhn.fhir.model.dstu2.valueset.MaritalStatusCodesEnum; import ca.uhn.fhir.parser.IParser; -public class ModelSerializationTest { +public class ModelSerializationDstu2Test { private static final FhirContext ourCtx = FhirContext.forDstu2(); + /** + * Verify that MaritalStatusCodeEnum (and, by extension, BoundCodeableConcepts in general) are serializable. Author: Nick Peterson (nrpeterson@gmail.com) + */ + @Test + public void testBoundCodeableConceptSerialization() { + MaritalStatusCodesEnum maritalStatus = MaritalStatusCodesEnum.M; + byte[] bytes = SerializationUtils.serialize(maritalStatus); + assertTrue(bytes.length > 0); + + MaritalStatusCodesEnum deserialized = SerializationUtils.deserialize(bytes); + assertEquals(maritalStatus.getCode(), deserialized.getCode()); + assertEquals(maritalStatus.getSystem(), deserialized.getSystem()); + } + + @Test + public void testBoundCodeSerialization() { + Patient p = new Patient(); + p.setGender(AdministrativeGenderEnum.MALE); + IdentifierDt identifier = p.addIdentifier(); + identifier.setType(IdentifierTypeCodesEnum.DL); + + Patient out = testIsSerializable(p); + + /* + * Make sure the binder still works for Code + */ + assertEquals(AdministrativeGenderEnum.MALE, out.getGenderElement().getValueAsEnum()); + out.getGenderElement().setValue("female"); + assertEquals(AdministrativeGenderEnum.FEMALE, out.getGenderElement().getValueAsEnum()); + + assertEquals(IdentifierTypeCodesEnum.DL, out.getIdentifier().get(0).getType().getValueAsEnum().iterator().next()); + out.getIdentifier().get(0).getType().setValueAsEnum(IdentifierTypeCodesEnum.MR); + assertEquals("MR", out.getIdentifier().get(0).getType().getCoding().get(0).getCode()); + assertEquals("http://hl7.org/fhir/v2/0203", out.getIdentifier().get(0).getType().getCoding().get(0).getSystem()); + } + + @SuppressWarnings("unchecked") + private T testIsSerializable(T theObject) { + byte[] bytes = SerializationUtils.serialize(theObject); + assertTrue(bytes.length > 0); + + IBaseResource obj = SerializationUtils.deserialize(bytes); + assertTrue(obj != null); + + IParser p = ourCtx.newXmlParser().setPrettyPrint(true); + assertEquals(p.encodeResourceToString(theObject), p.encodeResourceToString(obj)); + + return (T) obj; + } + @Test public void testSerialization() throws Exception { - String input = IOUtils.toString(ModelSerializationTest.class.getResourceAsStream("/diagnosticreport-examples-lab-text(72ac8493-52ac-41bd-8d5d-7258c289b5ea).xml")); + String input = IOUtils.toString(ModelSerializationDstu2Test.class.getResourceAsStream("/diagnosticreport-examples-lab-text(72ac8493-52ac-41bd-8d5d-7258c289b5ea).xml")); Bundle parsed = ourCtx.newXmlParser().parseResource(Bundle.class, input); testIsSerializable(parsed); @@ -44,31 +96,4 @@ public class ModelSerializationTest { testIsSerializable(patient); } - private void testIsSerializable(IBaseResource theObject) { - byte[] bytes = SerializationUtils.serialize(theObject); - assertTrue(bytes.length > 0); - - IBaseResource obj = SerializationUtils.deserialize(bytes); - assertTrue(obj != null); - - IParser p = ourCtx.newXmlParser().setPrettyPrint(true); - assertEquals(p.encodeResourceToString(theObject), p.encodeResourceToString(obj)); - - } - - /** - * Verify that MaritalStatusCodeEnum (and, by extension, BoundCodeableConcepts in general) are serializable. - * Author: Nick Peterson (nrpeterson@gmail.com) - */ - @Test - public void testBoundCodeableConceptSerialization() { - MaritalStatusCodesEnum maritalStatus = MaritalStatusCodesEnum.M; - byte[] bytes = SerializationUtils.serialize(maritalStatus); - assertTrue(bytes.length > 0); - - MaritalStatusCodesEnum deserialized = SerializationUtils.deserialize(bytes); - assertEquals(maritalStatus.getCode(), deserialized.getCode()); - assertEquals(maritalStatus.getSystem(), deserialized.getSystem()); - } - } diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/Enumeration.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/Enumeration.java index 9c871ff97d6..58778347953 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/Enumeration.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/Enumeration.java @@ -1,5 +1,10 @@ package org.hl7.fhir.dstu3.model; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + import org.hl7.fhir.instance.model.api.IBaseEnumeration; import ca.uhn.fhir.model.api.annotation.DatatypeDef; @@ -38,11 +43,20 @@ POSSIBILITY OF SUCH DAMAGE. * */ @DatatypeDef(name = "code", isSpecialization = true) -public class Enumeration> extends PrimitiveType implements IBaseEnumeration { +public class Enumeration> extends PrimitiveType implements IBaseEnumeration, Externalizable { private static final long serialVersionUID = 1L; - private final EnumFactory myEnumFactory; + private EnumFactory myEnumFactory; + /** + * Constructor + * @deprecated This no-arg constructor is provided for serialization only - Do not use + */ + @Deprecated + public Enumeration() { + // nothing + } + /** * Constructor */ @@ -100,4 +114,18 @@ public class Enumeration> extends PrimitiveType implements } return null; } + + @SuppressWarnings("unchecked") + @Override + public void readExternal(ObjectInput theIn) throws IOException, ClassNotFoundException { + myEnumFactory = (EnumFactory) theIn.readObject(); + super.readExternal(theIn); + } + + @Override + public void writeExternal(ObjectOutput theOut) throws IOException { + theOut.writeObject(myEnumFactory); + super.writeExternal(theOut); + } + } diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/PrimitiveType.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/PrimitiveType.java index fb10d429074..ec9cd59c732 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/PrimitiveType.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/PrimitiveType.java @@ -1,5 +1,10 @@ package org.hl7.fhir.dstu3.model; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -8,64 +13,18 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType; import ca.uhn.fhir.model.api.IElement; -public abstract class PrimitiveType extends Type implements IPrimitiveType, IBaseHasExtensions, IElement { +public abstract class PrimitiveType extends Type implements IPrimitiveType, IBaseHasExtensions, IElement, Externalizable { private static final long serialVersionUID = 3L; private T myCoercedValue; private String myStringValue; - public T getValue() { - return myCoercedValue; - } - public String asStringValue() { return myStringValue; } - @Override - public int hashCode() { - return new HashCodeBuilder().append(getValue()).toHashCode(); - } - - public PrimitiveType setValue(T theValue) { - myCoercedValue = theValue; - updateStringValue(); - return this; - } - - protected void updateStringValue() { - if (myCoercedValue == null) { - myStringValue = null; - } else { - // NB this might be null - myStringValue = encode(myCoercedValue); - } - } - - @Override - public boolean isEmpty() { - return super.isEmpty() && StringUtils.isBlank(getValueAsString()); - } - - public void fromStringValue(String theValue) { - if (theValue == null) { - myCoercedValue = null; - } else { - // NB this might be null - myCoercedValue = parse(theValue); - } - myStringValue = theValue; - } - - /** - * Subclasses must override to convert an encoded representation of this datatype into a "coerced" one - * - * @param theValue - * Will not be null - * @return May return null if the value does not correspond to anything - */ - protected abstract T parse(String theValue); + public abstract Type copy(); /** * Subclasses must override to convert a "coerced" value into an encoded one. @@ -76,37 +35,6 @@ public abstract class PrimitiveType extends Type implements IPrimitiveType */ protected abstract String encode(T theValue); - public boolean isPrimitive() { - return true; - } - - public String primitiveValue() { - return asStringValue(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + asStringValue() + "]"; - } - - public boolean hasValue() { - return !StringUtils.isBlank(getValueAsString()); - } - - public String getValueAsString() { - return asStringValue(); - } - - public void setValueAsString(String theValue) { - fromStringValue(theValue); - } - - protected Type typedCopy() { - return copy(); - } - - public abstract Type copy(); - @Override public boolean equalsDeep(Base obj) { if (!super.equalsDeep(obj)) @@ -141,4 +69,92 @@ public abstract class PrimitiveType extends Type implements IPrimitiveType return b.isEquals(); } + public void fromStringValue(String theValue) { + if (theValue == null) { + myCoercedValue = null; + } else { + // NB this might be null + myCoercedValue = parse(theValue); + } + myStringValue = theValue; + } + + public T getValue() { + return myCoercedValue; + } + + public String getValueAsString() { + return asStringValue(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(getValue()).toHashCode(); + } + + public boolean hasValue() { + return !StringUtils.isBlank(getValueAsString()); + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && StringUtils.isBlank(getValueAsString()); + } + + public boolean isPrimitive() { + return true; + } + + /** + * Subclasses must override to convert an encoded representation of this datatype into a "coerced" one + * + * @param theValue + * Will not be null + * @return May return null if the value does not correspond to anything + */ + protected abstract T parse(String theValue); + + public String primitiveValue() { + return asStringValue(); + } + + @Override + public void readExternal(ObjectInput theIn) throws IOException, ClassNotFoundException { + String object = (String) theIn.readObject(); + setValueAsString(object); + } + + public PrimitiveType setValue(T theValue) { + myCoercedValue = theValue; + updateStringValue(); + return this; + } + + public void setValueAsString(String theValue) { + fromStringValue(theValue); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + asStringValue() + "]"; + } + + protected Type typedCopy() { + return copy(); + } + + protected void updateStringValue() { + if (myCoercedValue == null) { + myStringValue = null; + } else { + // NB this might be null + myStringValue = encode(myCoercedValue); + } + } + + @Override + public void writeExternal(ObjectOutput theOut) throws IOException { + theOut.writeObject(getValueAsString()); + } + } diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/model/ModelSerializationDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/model/ModelSerializationDstu3Test.java new file mode 100644 index 00000000000..ad3468f419d --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/model/ModelSerializationDstu3Test.java @@ -0,0 +1,82 @@ +package ca.uhn.fhir.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Date; + +import org.apache.commons.lang3.SerializationUtils; +import org.hl7.fhir.dstu3.model.Address; +import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender; +import org.hl7.fhir.dstu3.model.HumanName; +import org.hl7.fhir.dstu3.model.Patient; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.TemporalPrecisionEnum; +import ca.uhn.fhir.parser.IParser; + +public class ModelSerializationDstu3Test { + + private static final FhirContext ourCtx = FhirContext.forDstu3(); + + /** + * Verify that MaritalStatusCodeEnum (and, by extension, BoundCodeableConcepts in general) are serializable. Author: Nick Peterson (nrpeterson@gmail.com) + */ + @Test + public void testBoundCodeableConceptSerialization() { + AdministrativeGender maritalStatus = AdministrativeGender.MALE; + byte[] bytes = SerializationUtils.serialize(maritalStatus); + assertTrue(bytes.length > 0); + + AdministrativeGender deserialized = SerializationUtils.deserialize(bytes); + assertEquals(AdministrativeGender.MALE, deserialized); + } + + @Test + public void testBoundCodeSerialization() { + Patient p = new Patient(); + p.setGender(AdministrativeGender.MALE); + + Patient out = testIsSerializable(p); + + /* + * Make sure the binder still works for Code + */ + assertEquals(AdministrativeGender.MALE, out.getGender()); + out.getGenderElement().setValueAsString("female"); + assertEquals(AdministrativeGender.FEMALE, out.getGender()); + + } + + @SuppressWarnings("unchecked") + private T testIsSerializable(T theObject) { + byte[] bytes = SerializationUtils.serialize(theObject); + assertTrue(bytes.length > 0); + + IBaseResource obj = SerializationUtils.deserialize(bytes); + assertTrue(obj != null); + + IParser p = ourCtx.newXmlParser().setPrettyPrint(true); + assertEquals(p.encodeResourceToString(theObject), p.encodeResourceToString(obj)); + + return (T) obj; + } + + /** + * Contributed by Travis from iSalus + */ + @Test + public void testSerialization2() { + Patient patient = new Patient(); + patient.addName(new HumanName().addGiven("George").addFamily("Washington")); + patient.addName(new HumanName().addGiven("George2").addFamily("Washington2")); + patient.addAddress(new Address().addLine("line 1").addLine("line 2").setCity("city").setState("UT")); + patient.addAddress(new Address().addLine("line 1b").addLine("line 2b").setCity("cityb").setState("UT")); + patient.setBirthDate(new Date()); + + testIsSerializable(patient); + } + +} diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 8b1d8de71f0..fe68ae082b5 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -216,6 +216,14 @@ requests where the URL does not contain an ID but needs to (e.g. for an update) or contains an ID but shouldn't (e.g. for a create) + + When fields of type BoundCodeDt (e.g. Patient.gender) + are serialized and deserialized using Java's native + object serialization, the enum binder was not + serialized too. This meant that values for the + field in the deserialized object could not be + modified. Thanks to Thomas Andersen for reporting! +