如何在Avro Union逻辑类型字段中指定转换器的默认值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Avro Union逻辑类型字段中指定转换器的默认值?相关的知识,希望对你有一定的参考价值。
我有以下Avro架构:
{
"namespace":"com.example",
"type":"record",
"name":"BuggyRecord",
"fields":[
{
"name":"my_mandatory_date",
"type":{
"type":"long",
"logicalType":"timestamp-millis"
},
"default":1502250227187
},
{
"name":"my_optional_date",
"type":[
{
"type":"long",
"logicalType":"timestamp-millis"
},
"null"
],
"default":1502250227187
}
]
}
我使用maven生成Java文件。 Avro配置:
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.8.2</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
<!--<goal>idl-protocol</goal>-->
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<enableDecimalLogicalType>true</enableDecimalLogicalType>
<stringType>String</stringType>
</configuration>
</execution>
</executions>
</plugin>
通过mvn compile
代码生成的类在一些基本代码上失败:
@Test
public void Foo(){
BuggyRecord.Builder buggyRecordBuilder = BuggyRecord.newBuilder();
buggyRecordBuilder.build();
}
错误代码:
org.apache.avro.AvroRuntimeException: java.lang.ClassCastException: java.lang.Long cannot be cast to org.joda.time.DateTime
at com.example.BuggyRecord$Builder.build(BuggyRecord.java:301)
at BuggyRecordTest.Foo(BuggyRecordTest.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to org.joda.time.DateTime
at com.example.BuggyRecord$Builder.build(BuggyRecord.java:298)
... 23 more
我认为是由于Converters
没有正确生成:
private static final org.apache.avro.Conversion<?>[] conversions =
new org.apache.avro.Conversion<?>[] {
TIMESTAMP_CONVERSION,
null, // <------ THIS ONE IS NOT SET PROPERLY
null
};
是我误用代码生成器还是错误?
答案
{
"name":"my_optional_date",
"type":[ "null", {"type" : "long", "logicalType": "timestamp-millis"}], "default": null
}
解决方法比解决方案更多 - 将“null”类型设置为first,将“default”设置为“default”:null
以上是关于如何在Avro Union逻辑类型字段中指定转换器的默认值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Messaging 中指定处理程序生成的内容类型?
是否通过 C99 中未指定的联合进行类型双关,并且它是否已在 C11 中指定?
是否通过 C99 中未指定的联合进行类型双关,并且它是否已在 C11 中指定?