[
https://issues.apache.org/jira/browse/AVRO-3224?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17425393#comment-17425393
]
Du Liu commented on AVRO-3224:
------------------------------
Hello, I think I found a fix with following patch:
{code:java}
diff --git
a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
index 20be49ec..ac736638 100644
---
a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
+++
b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
@@ -274,6 +274,7 @@ public class ReflectDatumReader<T> extends
SpecificDatumReader<T> {
throw new AvroRuntimeException("Failed to read Stringable", e);
}
}
+
LogicalType logicalType = field.schema().getLogicalType();
if (logicalType != null) {
Conversion<?> conversion =
getData().getConversionByClass(accessor.getField().getType(), logicalType);
@@ -287,6 +288,26 @@ public class ReflectDatumReader<T> extends
SpecificDatumReader<T> {
return;
}
}
+
+ if (field.schema().isUnion()) {
+ Schema innerSchema = field.schema().getTypes().get(in.readIndex());
+ LogicalType innerLogicalType = innerSchema.getLogicalType();
+
+ Object value = readWithoutConversion(oldDatum, innerSchema, in);
+ if (innerLogicalType != null) {
+ Conversion<?> conversion =
getData().getConversionByClass(accessor.getField().getType(), innerLogicalType);
+ if (conversion != null)
+ value = convert(value, innerSchema, innerLogicalType,
conversion);
+ }
+
+ try {
+ accessor.set(record, value);
+ } catch (IllegalAccessException e) {
+ throw new AvroRuntimeException("Failed to set " + field);
+ }
+ return;
+ }
+
try {
accessor.set(record, readWithoutConversion(oldDatum, field.schema(),
in));
return;
{code}
I also added a few more unit tests and opened a pull request here:
[https://github.com/apache/avro/pull/1355.] Thanks
> Wrong deserialisation when using ReflectData.AllowNull with custom
> LogicalType conversions
> ------------------------------------------------------------------------------------------
>
> Key: AVRO-3224
> URL: https://issues.apache.org/jira/browse/AVRO-3224
> Project: Apache Avro
> Issue Type: Bug
> Components: java
> Affects Versions: 1.10.2
> Reporter: Du Liu
> Priority: Minor
> Labels: pull-request-available
> Attachments: ReflectData.AllowNull.get doesnt work.png,
> ReflectData.get works.png, class_and_conversion.png, tests.txt
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> If a class contains both a java.time.LocalDate field and a java.sql.Date
> field, serialising an instance of the class using ReflectData.*AllowNull*
> with two conversions that both convert to avro date logical type (e.g. one
> converts java.time.LocalDate to avro date, the other converts java.sql.Date
> to avro date) is done correctly, but when deserialising the data back, the
> LocalDate field of the deserialised instance incorrectly contains a
> java.sql.Date (or the Date field incorrectly contains a LocalDate depending
> on which conversions is added last).
> This only happens when using ReflectData.*AllowNull*.get(). ReflectData.get()
> can correctly deserialised data back. I think this issue affects other types
> as long as two java types are mapped to the same avro logical type.
> A working example (using ReflectData.get()):
> !ReflectData.get works.png|width=887,height=379!
>
> A not working example (using ReflectData.AllowNull.get()):
> !ReflectData.AllowNull.get doesnt work.png|width=831,height=469!
> The class and conversion:
> !class_and_conversion.png|width=798,height=687!
>
> These tests are included in the attached patch file: [^tests.txt]
--
This message was sent by Atlassian Jira
(v8.3.4#803005)