diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index f33138d4afc..cc90e6eeef7 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -103,6 +103,8 @@ Optimizations * SOLR-9447: Do not clone SolrInputDocument if update processor chain does not contain custom processors. (shalin) +* SOLR-9452: JsonRecordReader should not deep copy document before handler.handle(). (noble, shalin) + Other Changes ---------------------- diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java b/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java index 2025197a005..782c25dc342 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java @@ -119,9 +119,8 @@ public class JsonRecordReader { */ public List> getAllRecords(Reader r) throws IOException { final List> results = new ArrayList<>(); - streamRecords(r, (record, path) -> { - results.add(record); - }); + // Deep copy is required here because the stream might hold on to the map + streamRecords(r, (record, path) -> results.add(Utils.getDeepCopy(record, 2))); return results; } @@ -279,23 +278,6 @@ public class JsonRecordReader { return n; } - /** - * Copies a supplied Map to a new Map which is returned. Used to copy a - * records values. If a fields value is a List then they have to be - * deep-copied for thread safety - */ - private static Map getDeepCopy(Map values) { - Map result = new LinkedHashMap<>(); - for (Map.Entry entry : values.entrySet()) { - if (entry.getValue() instanceof List) { - result.put(entry.getKey(), new ArrayList((List) entry.getValue())); - } else { - result.put(entry.getKey(), entry.getValue()); - } - } - return result; - } - private void parse(JSONParser parser, Handler handler, Map values) throws IOException { @@ -394,7 +376,7 @@ public class JsonRecordReader { int event = parser.nextEvent(); if (event == OBJECT_END) { if (isRecord()) { - handler.handle(getDeepCopy(values), splitPath); + handler.handle(values, splitPath); } return; } @@ -456,6 +438,7 @@ public class JsonRecordReader { } private void addChildDoc2ParentDoc(Map record, Map values) { + record = Utils.getDeepCopy(record, 2); Object oldVal = values.get(null); if (oldVal == null) { values.put(null, record);