|
1 | 1 | package com.fasterxml.jackson.dataformat.avro.schema;
|
2 | 2 |
|
3 | 3 | import java.util.*;
|
| 4 | +import java.util.stream.Collectors; |
4 | 5 |
|
5 | 6 | import org.apache.avro.LogicalTypes;
|
6 | 7 | import org.apache.avro.Schema;
|
@@ -85,56 +86,30 @@ public RecordVisitor(SerializerProvider p, JavaType type, VisitorFormatWrapperIm
|
85 | 86 |
|
86 | 87 | List<NamedType> subTypes = getProvider().getAnnotationIntrospector().findSubtypes(bean.getClassInfo());
|
87 | 88 | if (subTypes != null && !subTypes.isEmpty()) {
|
88 |
| - |
89 | 89 | // 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). |
96 | 92 | // 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 | + } |
104 | 98 | try {
|
105 | 99 | for (NamedType subType : subTypes) {
|
106 | 100 | JsonSerializer<?> ser = getProvider().findValueSerializer(subType.getType());
|
107 | 101 | VisitorFormatWrapperImpl visitor = _visitorWrapper.createChildWrapper();
|
108 | 102 | ser.acceptJsonFormatVisitor(visitor, getProvider().getTypeFactory().constructType(subType.getType()));
|
109 |
| - Schema subTypeSchema = visitor.getAvroSchema(); |
110 | 103 | // Add subType schema into this union, unless it is already there.
|
| 104 | + Schema subTypeSchema = visitor.getAvroSchema(); |
111 | 105 | // When subType schema is union itself, include each its type into this union if not there already
|
112 | 106 | 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 |
| -// } |
123 | 107 | unionSchemas.addAll(subTypeSchema.getTypes());
|
124 | 108 | } else {
|
125 |
| -// if (!unionSchemas.contains(subTypeSchema)) { |
126 |
| -// unionSchemas.add(subTypeSchema); |
127 |
| -// } |
128 | 109 | unionSchemas.add(subTypeSchema);
|
129 | 110 | }
|
130 | 111 | }
|
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)); |
138 | 113 | } catch (JsonMappingException jme) {
|
139 | 114 | throw new RuntimeException("Failed to build schema", jme);
|
140 | 115 | }
|
|
0 commit comments