Skip to content

Commit ef29a98

Browse files
committed
Using reference-equality Set for unionSchemas. It makes for simples code.
1 parent 8f09acc commit ef29a98

File tree

1 file changed

+10
-35
lines changed

1 file changed

+10
-35
lines changed

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/RecordVisitor.java

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.fasterxml.jackson.dataformat.avro.schema;
22

33
import java.util.*;
4+
import java.util.stream.Collectors;
45

56
import org.apache.avro.LogicalTypes;
67
import org.apache.avro.Schema;
@@ -85,56 +86,30 @@ public RecordVisitor(SerializerProvider p, JavaType type, VisitorFormatWrapperIm
8586

8687
List<NamedType> subTypes = getProvider().getAnnotationIntrospector().findSubtypes(bean.getClassInfo());
8788
if (subTypes != null && !subTypes.isEmpty()) {
88-
8989
// At this point calculating hashCode for _typeSchema fails with NPE because RecordSchema.fields is NULL
90-
// (see org.apache.avro.Schema.RecordSchema#computeHash).
91-
// Therefore, _typeSchema must be added into union at very end, or unionSchemas must not be HashSet (or any
92-
// other type calling hashCode() for equality check).
93-
Set<Schema> unionSchemas = new HashSet<>();
94-
// ArrayList<Schema> unionSchemas = new ArrayList<>();
95-
90+
// see org.apache.avro.Schema.RecordSchema#computeHash.
91+
// Therefore, unionSchemas must not be HashSet (or any other type using hashCode() for equality check).
9692
// IdentityHashMap is used because it is using reference-equality.
97-
// Set<Schema> unionSchemas = Collections.newSetFromMap(new IdentityHashMap<>());
98-
99-
// Initialize with this schema is
100-
// if (_type.isConcrete()) {
101-
// unionSchemas.add(_typeSchema);
102-
// }
103-
93+
Set<Schema> unionSchemas = Collections.newSetFromMap(new IdentityHashMap<>());
94+
// Initialize with this schema
95+
if (_type.isConcrete()) {
96+
unionSchemas.add(_typeSchema);
97+
}
10498
try {
10599
for (NamedType subType : subTypes) {
106100
JsonSerializer<?> ser = getProvider().findValueSerializer(subType.getType());
107101
VisitorFormatWrapperImpl visitor = _visitorWrapper.createChildWrapper();
108102
ser.acceptJsonFormatVisitor(visitor, getProvider().getTypeFactory().constructType(subType.getType()));
109-
Schema subTypeSchema = visitor.getAvroSchema();
110103
// Add subType schema into this union, unless it is already there.
104+
Schema subTypeSchema = visitor.getAvroSchema();
111105
// When subType schema is union itself, include each its type into this union if not there already
112106
if (subTypeSchema.getType() == Type.UNION) {
113-
// subTypeSchema.getTypes().stream()
114-
// .filter(unionElement -> !unionSchemas.contains(unionElement))
115-
// .forEach(unionSchemas::add);
116-
// or
117-
// for( Schema unionElement: subTypeSchema.getTypes()) {
118-
// if (unionSchemas.contains(unionElement)) {
119-
// continue;
120-
// }
121-
// unionSchemas.add(unionElement);
122-
// }
123107
unionSchemas.addAll(subTypeSchema.getTypes());
124108
} else {
125-
// if (!unionSchemas.contains(subTypeSchema)) {
126-
// unionSchemas.add(subTypeSchema);
127-
// }
128109
unionSchemas.add(subTypeSchema);
129110
}
130111
}
131-
132-
ArrayList<Schema> unionList = new ArrayList<>(unionSchemas);
133-
// add _type schema into union
134-
if (_type.isConcrete()) {
135-
unionList.add(_typeSchema);
136-
}
137-
_avroSchema = Schema.createUnion(unionList);
112+
_avroSchema = Schema.createUnion(new ArrayList<>(unionSchemas));
138113
} catch (JsonMappingException jme) {
139114
throw new RuntimeException("Failed to build schema", jme);
140115
}

0 commit comments

Comments
 (0)