diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java index 4457b401..847b1fca 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java @@ -108,7 +108,7 @@ public class QRecord implements Serializable /******************************************************************************* - ** Copy constructor. + ** Copy constructor. Makes a deep clone. ** *******************************************************************************/ public QRecord(QRecord record) @@ -120,10 +120,10 @@ public class QRecord implements Serializable this.displayValues = deepCopySimpleMap(record.displayValues); this.backendDetails = deepCopySimpleMap(record.backendDetails); - this.associatedRecords = deepCopyAssociatedRecords(record.associatedRecords); - this.errors = record.errors == null ? null : new ArrayList<>(record.errors); this.warnings = record.warnings == null ? null : new ArrayList<>(record.warnings); + + this.associatedRecords = deepCopyAssociatedRecords(record.associatedRecords); } @@ -143,17 +143,17 @@ public class QRecord implements Serializable ** todo - move to a cloning utils maybe? *******************************************************************************/ @SuppressWarnings({ "unchecked" }) - private Map deepCopySimpleMap(Map map) + private Map deepCopySimpleMap(Map map) { if(map == null) { return (null); } - Map clone = new LinkedHashMap<>(); - for(Map.Entry entry : map.entrySet()) + Map clone = new LinkedHashMap<>(); + for(Map.Entry entry : map.entrySet()) { - V value = entry.getValue(); + Serializable value = entry.getValue(); ////////////////////////////////////////////////////////////////////////// // not sure from where/how java.sql.Date objects are getting in here... // @@ -167,15 +167,17 @@ public class QRecord implements Serializable ArrayList cloneList = new ArrayList<>(arrayList); clone.put(entry.getKey(), (V) cloneList); } - else if(entry.getValue() instanceof Serializable serializableValue) + else if(entry.getValue() instanceof QRecord otherQRecord) { - LOG.info("Non-primitive serializable value in QRecord - calling SerializationUtils.clone...", logPair("key", entry.getKey()), logPair("type", value.getClass())); - clone.put(entry.getKey(), (V) SerializationUtils.clone(serializableValue)); + clone.put(entry.getKey(), (V) new QRecord(otherQRecord)); } else { - LOG.warn("Non-serializable value in QRecord...", logPair("key", entry.getKey()), logPair("type", value.getClass())); - clone.put(entry.getKey(), entry.getValue()); + ////////////////////////////////////////////////////////////////////////////// + // we know entry is serializable at this point, based on type param's bound // + ////////////////////////////////////////////////////////////////////////////// + LOG.info("Non-primitive serializable value in QRecord - calling SerializationUtils.clone...", logPair("key", entry.getKey()), logPair("type", value.getClass())); + clone.put(entry.getKey(), (V) SerializationUtils.clone(entry.getValue())); } } return (clone); diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java index 8fc66dea..73b63c72 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java @@ -151,6 +151,14 @@ class QRecordTest extends BaseTest QRecord recordWithArrayListValue = new QRecord().withValue("myList", originalArrayList); QRecord cloneWithArrayListValue = new QRecord(recordWithArrayListValue); + //////////////////////////////////////////// + // qrecord as a value inside another (!?) // + //////////////////////////////////////////// + QRecord nestedQRecordValue = new QRecord().withValue("myRecord", new QRecord().withValue("A", 1)); + QRecord cloneWithNestedQRecord = new QRecord(nestedQRecordValue); + assertEquals(1, ((QRecord) cloneWithNestedQRecord.getValue("myRecord")).getValueInteger("A")); + assertNotSame(cloneWithNestedQRecord.getValue("myRecord"), nestedQRecordValue.getValue("myRecord")); + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // the clone list and original list should be equals (have contents that are equals), but not be the same (reference) // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////