java - 为什么字符串的 Avro 字段现在需要 avro.java.string 类型?
问题描述
在 Avro IDL 中,我有一条消息记录,定义如下:
record Message{
MessageId id;
array<string> dataField;
}
我在另一个具有空联合的记录中使用此记录:
record Invoice{
...
union {null,array<Message>} message;
}
我们有一个使用 1.10.2 版本的 Java Kafka 消费者(我们正在使用 Confluent 平台)avro-maven-plugin
,配置为<stringType>String</stringType>
当我们拨打这样的电话时:
List<String> msgList = message.getDataField();
for (String msg : msgList) {...}
我们在第二行收到以下错误:class org.apache.avro.util.Utf8 cannot be cast to class java.lang.String
以前,Invoice 对象被定义为:
record Invoice{
...
array<Message> message;
}
我们没有收到这个错误。我们发现在我们的模式文件中,从
"name" : "dataField",
"type" : {
"type" : "array",
"items" : "string"
}
至
"name" : "dataField",
"type" : {
"type" : "array",
"items" :{
"type": "string",
"avro.java.string" : "String"
}
}
纠正问题。
我不清楚为什么添加工会会导致这种行为变化。我是否应该使用 声明架构中的所有字符串,avro.java.string
如果是,我该如何使用 Avro IDL 来做到这一点?
解决方案
在这一点上,似乎有几种方法可以解决这个问题,至少在使用 Confluent Platform 5.5.1 或更高版本时是这样。我认为这个问题是 Avro 的一个公开缺陷。
第一个选项是使用全局搜索更新 Avro Schema 文件并将其替换"type":"string"
为
"type": {
"avro.java.string": "String",
"type": "string"
}
第一个选项需要在通过 Avro IDL 创建任何文件后完成,因为它不支持这种结构,这使得 IDL 在这种情况下不太有用。奇怪的是,这种方法似乎不会影响通过 REST 代理传入的、在"type":"string"
没有附加avro.java.string
信息的情况下关联的记录。他们似乎能够使用以任何一种方式定义的模式;我期待带有avro.java.string
信息的更新架构会导致没有该详细信息的 REST 代理请求出现问题。
第二个选项是设置auto.register.schemas=false
and use.latest.version=true
,尽管这可能会在将来导致与兼容性有关的意外后果。
第三个选项是不使用<stringType>
Avro Tools 的 Maven 配置中的指令。这意味着围绕CharacterSequence
默认使用的大量编码,通常以.toString()
方法的形式。
推荐阅读
- c - 无法使用 esp32 从 firebase 获取正确的数据。每次我使用get函数时,串口监视器的输出都是0
- python - 将字符串转换为数据框中列内的整数(5 星级 = 5)
- java - 仅插入小数位时如何阻止应用程序崩溃
- java - Java没有从列表中删除特定项目
- elasticsearch - Elasticsearch:如果任何嵌套对象字段与术语值匹配,则不返回文档
- python - 有没有办法在 Tkinter 文本小部件的插入点获取行号?
- linux - 为什么有时 init 进程读取 /dev/initctl 返回 -1?
- dataframe - 在 Jupyter Notebook 的列标题中显示带有数学符号的 DataFrame
- sql - SQL如何显示单独的元素
- c# - 添加迁移挂起使用上下文 - 没有错误