|
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