【问题标题】:Avro: org.apache.avro.AvroTypeException: Expected long. Got START_OBJECTAvro:org.apache.avro.AvroTypeException:预计很长。得到了 START_OBJECT
【发布时间】:2022-01-11 11:38:20
【问题描述】:

我正在研究 Avro 架构并尝试创建测试数据以使用 Kafa 对其进行测试,但是当我生成消息时收到此错误:“Caused by: org.apache.avro.AvroTypeException: Expected long. Got START_OBJECT " 我创建的 Schema 是这样的:

{
    "name": "MyClass",
    "type": "record",
    "namespace": "com.acme.avro",
    "doc":"This schema is for streaming information",
    "fields":[
        {"name":"batchId", "type": "long"},
        {"name":"status", "type": {"type": "enum", "name": "PlannedTripRequestedStatus", "namespace":"com.acme.avro.Dtos", "symbols":["COMPLETED", "FAILED"]}},
        {"name":"runRefId", "type": "int"},
        {"name":"tripId", "type": ["null", "int"]},
        {"name": "referenceNumber", "type": ["null", "string"]},
        {"name":"errorMessage", "type": ["null", "string"]}
    ]
}

测试数据是这样的:

{
    "batchId": {
        "long": 3
    },
    "status": "COMPLETED",
    "runRefId": {
        "int": 1000
    },
    "tripId": {
        "int": 200
    },
    "referenceNumber": {
        "string": "ReferenceNumber1111"
    },
    "errorMessage": {
        "string": "Hello World"
    }
}

但是,当我注册此架构并尝试使用 Confluent 控制台工具生成消息时,我收到错误:org.apache.avro.AvroTypeException: Expected long。 Got START_OBJECT 整个错误信息是这样的:

org.apache.kafka.common.errors.SerializationException: Error deserializing {"batchId": ...} to Avro of schema {"type":...}" at io.confluent.kafka.formatter.AvroMessageReader.readFrom(AvroMessageReader.java:134)
    at io.confluent.kafka.formatter.SchemaMessageReader.readMessage(SchemaMessageReader.java:325)
    at kafka.tools.ConsoleProducer$.main(ConsoleProducer.scala:51)
    at kafka.tools.ConsoleProducer.main(ConsoleProducer.scala)
Caused by: org.apache.avro.AvroTypeException: Expected long. Got START_OBJECT
    at org.apache.avro.io.JsonDecoder.error(JsonDecoder.java:511)
    at org.apache.avro.io.JsonDecoder.readLong(JsonDecoder.java:177)
    at org.apache.avro.io.ResolvingDecoder.readLong(ResolvingDecoder.java:169)
    at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:197)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:160)
    at org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:259)
    at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:247)
    at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:179)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:160)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:153)
    at io.confluent.kafka.schemaregistry.avro.AvroSchemaUtils.toObject(AvroSchemaUtils.java:213)
    at io.confluent.kafka.formatter.AvroMessageReader.readFrom(AvroMessageReader.java:124)

有谁知道我的架构或测试数据做错了什么?非常感谢!

【问题讨论】:

    标签: apache-kafka avro


    【解决方案1】:

    只有在类型不明确(例如字符串或数字的联合)或其可为空时才需要类型对象。

    对于 batchId 和 runRefId,只需使用简单的值

    【讨论】:

    • 非常感谢!当我将 batchId 和 runRefId 更改为这样的数字时,它可以工作: {"batchId": 3,"status":"COMPLETED","runRefId":1000,"tripId":{"int":200},"referenceNumber" :{"string":"referenceNumber1111"},"errorMessage":{"string":"Hello World"}}。但是,如果我将tripId 更改为数字,它会再次损坏。我能问一下为什么我不能在这里为 tripId 使用简单的值吗?或者我可以参考的任何 avro 模式 json 验证文档?再次感谢您
    • @ZichenMa 回答,可空字段需要类型信息
    • tripId 不能使用简单值的原因是因为它是一个联合体,并且规范规定联合体需要类型信息(除非该值为 null)。您可以在此处阅读规范的该部分:avro.apache.org/docs/current/spec.html#json_encoding
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2020-08-05
    • 1970-01-01
    • 2016-07-28
    相关资源
    最近更新 更多