avro工具版本-1.9.2
这是我在反序列化avro数据时面临的问题。看起来avro无法生成正确的pojo类,当字段与null和逻辑类型并集时。
当前行为:当avro模式的字段是null和逻辑类型的并集时。avro不添加转换类型数组,因此我们得到类强制转换异常。这就是original.avsc的问题
预期行为:avro应该能够序列化具有空值的逻辑类型。
看一下下面的original.avsc,没有 conversions
为任何字段创建的数组。结果是 ClassCastException
因为原始字段数据是基元类型,而pojo字段是基于逻辑类型的。
原始.avsc
{
"type": "record",
"name": "UserRecord",
"namespace": "com.original",
"fields": [
{
"name": "user",
"type": {
"type": "record",
"name": "User",
"fields": [
{
"name": "KEY_NBR",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "CRTE_TMS",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-micros"
}
],
"default": null
},
{
"name": "BIRTH_DT",
"type": [
"null",
{
"type": "int",
"logicalType": "date"
}
],
"default": null
},
{
"name": "BAL_AMT",
"type": [
"null",
{
"type": "bytes",
"precision": 7,
"scale": 2,
"logicalType": "decimal"
}
],
"default": null
}
]
}
},
{
"name": "beforeUser",
"type": [
"null",
"User"
],
"default": null
}
]
}
基于original.avsc的pojo
package com.original;
import org.apache.avro.generic.GenericArray;
import org.apache.avro.specific.SpecificData;
import org.apache.avro.util.Utf8;
import org.apache.avro.message.BinaryMessageEncoder;
import org.apache.avro.message.BinaryMessageDecoder;
import org.apache.avro.message.SchemaStore;
@org.apache.avro.specific.AvroGenerated
public class User extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
private static final long serialVersionUID = 4336376255546547414L;
public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.original\",\"fields\":[{\"name\":\"KEY_NBR\",\"type\":[\"null\",\"string\"],\"default\":null},{\"name\":\"CRTE_TMS\",\"type\":[\"null\",{\"type\":\"long\",\"logicalType\":\"timestamp-micros\"}],\"default\":null},{\"name\":\"BIRTH_DT\",\"type\":[\"null\",{\"type\":\"int\",\"logicalType\":\"date\"}],\"default\":null},{\"name\":\"BAL_AMT\",\"type\":[\"null\",{\"type\":\"bytes\",\"precision\":7,\"scale\":2,\"logicalType\":\"decimal\"}],\"default\":null}]}");
public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
private static SpecificData MODEL$ = new SpecificData();
static {
MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.DateConversion());
MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.TimestampMillisConversion());
}
private static final BinaryMessageEncoder<User> ENCODER =
new BinaryMessageEncoder<User>(MODEL$, SCHEMA$);
private static final BinaryMessageDecoder<User> DECODER =
new BinaryMessageDecoder<User>(MODEL$, SCHEMA$);
public static BinaryMessageEncoder<User> getEncoder() {
return ENCODER;
}
public static BinaryMessageDecoder<User> getDecoder() {
return DECODER;
}
public static BinaryMessageDecoder<User> createDecoder(SchemaStore resolver) {
return new BinaryMessageDecoder<User>(MODEL$, SCHEMA$, resolver);
}
public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
return ENCODER.encode(this);
}
public static User fromByteBuffer(
java.nio.ByteBuffer b) throws java.io.IOException {
return DECODER.decode(b);
}
private java.lang.CharSequence KEY_NBR;
private java.time.Instant CRTE_TMS;
private java.time.LocalDate BIRTH_DT;
private java.nio.ByteBuffer BAL_AMT;
public User() {}
public User(java.lang.CharSequence KEY_NBR, java.time.Instant CRTE_TMS, java.time.LocalDate BIRTH_DT, java.nio.ByteBuffer BAL_AMT) {
this.KEY_NBR = KEY_NBR;
this.CRTE_TMS = CRTE_TMS;
this.BIRTH_DT = BIRTH_DT;
this.BAL_AMT = BAL_AMT;
}
public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
public org.apache.avro.Schema getSchema() { return SCHEMA$; }
// Used by DatumWriter. Applications should not call.
public java.lang.Object get(int field$) {
switch (field$) {
case 0: return KEY_NBR;
case 1: return CRTE_TMS;
case 2: return BIRTH_DT;
case 3: return BAL_AMT;
default: throw new org.apache.avro.AvroRuntimeException("Bad index");
}
}
// Used by DatumReader. Applications should not call.
@SuppressWarnings(value="unchecked")
public void put(int field$, java.lang.Object value$) {
switch (field$) {
case 0: KEY_NBR = (java.lang.CharSequence)value$; break;
case 1: CRTE_TMS = (java.time.Instant)value$; break;
case 2: BIRTH_DT = (java.time.LocalDate)value$; break;
case 3: BAL_AMT = (java.nio.ByteBuffer)value$; break;
default: throw new org.apache.avro.AvroRuntimeException("Bad index");
}
}
public java.lang.CharSequence getKEYNBR() {
return KEY_NBR;
}
/**
* Sets the value of the 'KEY_NBR' field.
* @param value the value to set.
*/
public void setKEYNBR(java.lang.CharSequence value) {
this.KEY_NBR = value;
}
public java.time.Instant getCRTETMS() {
return CRTE_TMS;
}
/**
* Sets the value of the 'CRTE_TMS' field.
* @param value the value to set.
*/
public void setCRTETMS(java.time.Instant value) {
this.CRTE_TMS = value;
}
/**
* Gets the value of the 'BIRTH_DT' field.
* @return The value of the 'BIRTH_DT' field.
*/
public java.time.LocalDate getBIRTHDT() {
return BIRTH_DT;
}
public void setBIRTHDT(java.time.LocalDate value) {
this.BIRTH_DT = value;
}
/**
* Gets the value of the 'BAL_AMT' field.
* @return The value of the 'BAL_AMT' field.
*/
public java.nio.ByteBuffer getBALAMT() {
return BAL_AMT;
}
/**
* Sets the value of the 'BAL_AMT' field.
* @param value the value to set.
*/
public void setBALAMT(java.nio.ByteBuffer value) {
this.BAL_AMT = value;
}
/**
* Creates a new User RecordBuilder.
* @return A new User RecordBuilder
*/
public static com.original.User.Builder newBuilder() {
return new com.original.User.Builder();
}
public static com.original.User.Builder newBuilder(com.original.User.Builder other) {
if (other == null) {
return new com.original.User.Builder();
} else {
return new com.original.User.Builder(other);
}
}
public static com.original.User.Builder newBuilder(com.original.User other) {
if (other == null) {
return new com.original.User.Builder();
} else {
return new com.original.User.Builder(other);
}
}
@org.apache.avro.specific.AvroGenerated
public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<User>
implements org.apache.avro.data.RecordBuilder<User> {
private java.lang.CharSequence KEY_NBR;
private java.time.Instant CRTE_TMS;
private java.time.LocalDate BIRTH_DT;
private java.nio.ByteBuffer BAL_AMT;
private Builder() {
super(SCHEMA$);
}
private Builder(com.original.User.Builder other) {
super(other);
if (isValidValue(fields()[0], other.KEY_NBR)) {
this.KEY_NBR = data().deepCopy(fields()[0].schema(), other.KEY_NBR);
fieldSetFlags()[0] = other.fieldSetFlags()[0];
}
if (isValidValue(fields()[1], other.CRTE_TMS)) {
this.CRTE_TMS = data().deepCopy(fields()[1].schema(), other.CRTE_TMS);
fieldSetFlags()[1] = other.fieldSetFlags()[1];
}
if (isValidValue(fields()[2], other.BIRTH_DT)) {
this.BIRTH_DT = data().deepCopy(fields()[2].schema(), other.BIRTH_DT);
fieldSetFlags()[2] = other.fieldSetFlags()[2];
}
if (isValidValue(fields()[3], other.BAL_AMT)) {
this.BAL_AMT = data().deepCopy(fields()[3].schema(), other.BAL_AMT);
fieldSetFlags()[3] = other.fieldSetFlags()[3];
}
}
private Builder(com.original.User other) {
super(SCHEMA$);
if (isValidValue(fields()[0], other.KEY_NBR)) {
this.KEY_NBR = data().deepCopy(fields()[0].schema(), other.KEY_NBR);
fieldSetFlags()[0] = true;
}
if (isValidValue(fields()[1], other.CRTE_TMS)) {
this.CRTE_TMS = data().deepCopy(fields()[1].schema(), other.CRTE_TMS);
fieldSetFlags()[1] = true;
}
if (isValidValue(fields()[2], other.BIRTH_DT)) {
this.BIRTH_DT = data().deepCopy(fields()[2].schema(), other.BIRTH_DT);
fieldSetFlags()[2] = true;
}
if (isValidValue(fields()[3], other.BAL_AMT)) {
this.BAL_AMT = data().deepCopy(fields()[3].schema(), other.BAL_AMT);
fieldSetFlags()[3] = true;
}
}
public java.lang.CharSequence getKEYNBR() {
return KEY_NBR;
}
public com.original.User.Builder setKEYNBR(java.lang.CharSequence value) {
validate(fields()[0], value);
this.KEY_NBR = value;
fieldSetFlags()[0] = true;
return this;
}
public boolean hasKEYNBR() {
return fieldSetFlags()[0];
}
public com.original.User.Builder clearKEYNBR() {
KEY_NBR = null;
fieldSetFlags()[0] = false;
return this;
}
/**
* Gets the value of the 'CRTE_TMS' field.
* @return The value.
*/
public java.time.Instant getCRTETMS() {
return CRTE_TMS;
}
public com.original.User.Builder setCRTETMS(java.time.Instant value) {
validate(fields()[1], value);
this.CRTE_TMS = value;
fieldSetFlags()[1] = true;
return this;
}
/**
* Checks whether the 'CRTE_TMS' field has been set.
* @return True if the 'CRTE_TMS' field has been set, false otherwise.
*/
public boolean hasCRTETMS() {
return fieldSetFlags()[1];
}
public com.original.User.Builder clearCRTETMS() {
CRTE_TMS = null;
fieldSetFlags()[1] = false;
return this;
}
public java.time.LocalDate getBIRTHDT() {
return BIRTH_DT;
}
public com.original.User.Builder setBIRTHDT(java.time.LocalDate value) {
validate(fields()[2], value);
this.BIRTH_DT = value;
fieldSetFlags()[2] = true;
return this;
public boolean hasBIRTHDT() {
return fieldSetFlags()[2];
}
/**
* Clears the value of the 'BIRTH_DT' field.
* @return This builder.
*/
public com.original.User.Builder clearBIRTHDT() {
BIRTH_DT = null;
fieldSetFlags()[2] = false;
return this;
}
/**
* Gets the value of the 'BAL_AMT' field.
* @return The value.
*/
public java.nio.ByteBuffer getBALAMT() {
return BAL_AMT;
}
public com.original.User.Builder setBALAMT(java.nio.ByteBuffer value) {
validate(fields()[3], value);
this.BAL_AMT = value;
fieldSetFlags()[3] = true;
return this;
}
/**
* Checks whether the 'BAL_AMT' field has been set.
* @return True if the 'BAL_AMT' field has been set, false otherwise.
*/
public boolean hasBALAMT() {
return fieldSetFlags()[3];
}
public com.original.User.Builder clearBALAMT() {
BAL_AMT = null;
fieldSetFlags()[3] = false;
return this;
}
@Override
@SuppressWarnings("unchecked")
public User build() {
try {
User record = new User();
record.KEY_NBR = fieldSetFlags()[0] ? this.KEY_NBR : (java.lang.CharSequence) defaultValue(fields()[0]);
record.CRTE_TMS = fieldSetFlags()[1] ? this.CRTE_TMS : (java.time.Instant) defaultValue(fields()[1]);
record.BIRTH_DT = fieldSetFlags()[2] ? this.BIRTH_DT : (java.time.LocalDate) defaultValue(fields()[2]);
record.BAL_AMT = fieldSetFlags()[3] ? this.BAL_AMT : (java.nio.ByteBuffer) defaultValue(fields()[3]);
return record;
} catch (org.apache.avro.AvroMissingFieldException e) {
throw e;
} catch (java.lang.Exception e) {
throw new org.apache.avro.AvroRuntimeException(e);
}
}
}
@SuppressWarnings("unchecked")
private static final org.apache.avro.io.DatumWriter<User>
WRITER$ = (org.apache.avro.io.DatumWriter<User>)MODEL$.createDatumWriter(SCHEMA$);
@Override public void writeExternal(java.io.ObjectOutput out)
throws java.io.IOException {
WRITER$.write(this, SpecificData.getEncoder(out));
}
@SuppressWarnings("unchecked")
private static final org.apache.avro.io.DatumReader<User>
READER$ = (org.apache.avro.io.DatumReader<User>)MODEL$.createDatumReader(SCHEMA$);
@Override public void readExternal(java.io.ObjectInput in)
throws java.io.IOException {
READER$.read(this, SpecificData.getDecoder(in));
}
}
然而,如果我修改原始模式并从逻辑类型字段中取出空值。avro生成适当的 conversions
(选中突出显示的部分)的逻辑类型字段,我能够成功地将avro消息反序列化到pojo。
修改.avsc
{
"type": "record",
"name": "UserRecord",
"namespace": "com.modified",
"fields": [
{
"name": "user",
"type": {
"type": "record",
"name": "User",
"fields": [
{
"name": "KEY_NBR",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "CRTE_TMS",
"type":
{
"type": "long",
"logicalType": "timestamp-micros"
},
"default": 1
},
{
"name": "BIRTH_DT",
"type":
{
"type": "int",
"logicalType": "date"
},
"default": 1
},
{
"name": "BAL_AMT",
"type":
{
"type": "bytes",
"precision": 7,
"scale": 2,
"logicalType": "decimal"
}
}
]
}
},
{
"name": "beforeUser",
"type": [
"null",
"User"
],
"default": null
}
]
}
从修改的架构生成的pojo类
package com.modified;
import org.apache.avro.generic.GenericArray;
import org.apache.avro.specific.SpecificData;
import org.apache.avro.util.Utf8;
import org.apache.avro.message.BinaryMessageEncoder;
import org.apache.avro.message.BinaryMessageDecoder;
import org.apache.avro.message.SchemaStore;
@org.apache.avro.specific.AvroGenerated
public class User extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
private static final long serialVersionUID = -2671150121474031299L;
public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.modified\",\"fields\":[{\"name\":\"KEY_NBR\",\"type\":[\"null\",\"string\"],\"default\":null},{\"name\":\"CRTE_TMS\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-micros\"},\"default\":1},{\"name\":\"BIRTH_DT\",\"type\":{\"type\":\"int\",\"logicalType\":\"date\"},\"default\":1},{\"name\":\"BAL_AMT\",\"type\":{\"type\":\"bytes\",\"precision\":7,\"scale\":2,\"logicalType\":\"decimal\"}}]}");
public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
private static SpecificData MODEL$ = new SpecificData();
static {
MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.DateConversion());
MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.TimestampMillisConversion());
}
private static final BinaryMessageEncoder<User> ENCODER =
new BinaryMessageEncoder<User>(MODEL$, SCHEMA$);
private static final BinaryMessageDecoder<User> DECODER =
new BinaryMessageDecoder<User>(MODEL$, SCHEMA$);
public static BinaryMessageEncoder<User> getEncoder() {
return ENCODER;
}
public static BinaryMessageDecoder<User> getDecoder() {
return DECODER;
}
public static BinaryMessageDecoder<User> createDecoder(SchemaStore resolver) {
return new BinaryMessageDecoder<User>(MODEL$, SCHEMA$, resolver);
}
public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
return ENCODER.encode(this);
}
public static User fromByteBuffer(
java.nio.ByteBuffer b) throws java.io.IOException {
return DECODER.decode(b);
}
private java.lang.CharSequence KEY_NBR;
private java.time.Instant CRTE_TMS;
private java.time.LocalDate BIRTH_DT;
private java.nio.ByteBuffer BAL_AMT;
public User() {}
public User(java.lang.CharSequence KEY_NBR, java.time.Instant CRTE_TMS, java.time.LocalDate BIRTH_DT, java.nio.ByteBuffer BAL_AMT) {
this.KEY_NBR = KEY_NBR;
this.CRTE_TMS = CRTE_TMS.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
this.BIRTH_DT = BIRTH_DT;
this.BAL_AMT = BAL_AMT;
}
public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
public org.apache.avro.Schema getSchema() { return SCHEMA$; }
// Used by DatumWriter. Applications should not call.
public java.lang.Object get(int field$) {
switch (field$) {
case 0: return KEY_NBR;
case 1: return CRTE_TMS;
case 2: return BIRTH_DT;
case 3: return BAL_AMT;
default: throw new org.apache.avro.AvroRuntimeException("Bad index");
}
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// This was missing from original POJO class thus failing deserialization
private static final org.apache.avro.Conversion<?>[] conversions =
new org.apache.avro.Conversion<?>[] {
null,
new org.apache.avro.data.TimeConversions.TimestampMicrosConversion(),
new org.apache.avro.data.TimeConversions.DateConversion(),
null,
null
};
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@Override
public org.apache.avro.Conversion<?> getConversion(int field) {
return conversions[field];
}
// Used by DatumReader. Applications should not call.
@SuppressWarnings(value="unchecked")
public void put(int field$, java.lang.Object value$) {
switch (field$) {
case 0: KEY_NBR = (java.lang.CharSequence)value$; break;
case 1: CRTE_TMS = (java.time.Instant)value$; break;
case 2: BIRTH_DT = (java.time.LocalDate)value$; break;
case 3: BAL_AMT = (java.nio.ByteBuffer)value$; break;
default: throw new org.apache.avro.AvroRuntimeException("Bad index");
}
}
public java.lang.CharSequence getKEYNBR() {
return KEY_NBR;
}
public void setKEYNBR(java.lang.CharSequence value) {
this.KEY_NBR = value;
}
public java.time.Instant getCRTETMS() {
return CRTE_TMS;
}
public void setCRTETMS(java.time.Instant value) {
this.CRTE_TMS = value.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
}
public java.time.LocalDate getBIRTHDT() {
return BIRTH_DT;
}
public void setBIRTHDT(java.time.LocalDate value) {
this.BIRTH_DT = value;
}
public java.nio.ByteBuffer getBALAMT() {
return BAL_AMT;
}
public void setBALAMT(java.nio.ByteBuffer value) {
this.BAL_AMT = value;
}
public static com.modified.User.Builder newBuilder() {
return new com.modified.User.Builder();
}
public static com.modified.User.Builder newBuilder(com.modified.User.Builder other) {
if (other == null) {
return new com.modified.User.Builder();
} else {
return new com.modified.User.Builder(other);
}
}
public static com.modified.User.Builder newBuilder(com.modified.User other) {
if (other == null) {
return new com.modified.User.Builder();
} else {
return new com.modified.User.Builder(other);
}
}
@org.apache.avro.specific.AvroGenerated
public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<User>
implements org.apache.avro.data.RecordBuilder<User> {
private java.lang.CharSequence KEY_NBR;
private java.time.Instant CRTE_TMS;
private java.time.LocalDate BIRTH_DT;
private java.nio.ByteBuffer BAL_AMT;
/**Creates a new Builder */
private Builder() {
super(SCHEMA$);
}
private Builder(com.modified.User.Builder other) {
super(other);
if (isValidValue(fields()[0], other.KEY_NBR)) {
this.KEY_NBR = data().deepCopy(fields()[0].schema(), other.KEY_NBR);
fieldSetFlags()[0] = other.fieldSetFlags()[0];
}
if (isValidValue(fields()[1], other.CRTE_TMS)) {
this.CRTE_TMS = data().deepCopy(fields()[1].schema(), other.CRTE_TMS);
fieldSetFlags()[1] = other.fieldSetFlags()[1];
}
if (isValidValue(fields()[2], other.BIRTH_DT)) {
this.BIRTH_DT = data().deepCopy(fields()[2].schema(), other.BIRTH_DT);
fieldSetFlags()[2] = other.fieldSetFlags()[2];
}
if (isValidValue(fields()[3], other.BAL_AMT)) {
this.BAL_AMT = data().deepCopy(fields()[3].schema(), other.BAL_AMT);
fieldSetFlags()[3] = other.fieldSetFlags()[3];
}
}
/**
* Creates a Builder by copying an existing User instance
* @param other The existing instance to copy.
*/
private Builder(com.modified.User other) {
super(SCHEMA$);
if (isValidValue(fields()[0], other.KEY_NBR)) {
this.KEY_NBR = data().deepCopy(fields()[0].schema(), other.KEY_NBR);
fieldSetFlags()[0] = true;
}
if (isValidValue(fields()[1], other.CRTE_TMS)) {
this.CRTE_TMS = data().deepCopy(fields()[1].schema(), other.CRTE_TMS);
fieldSetFlags()[1] = true;
}
if (isValidValue(fields()[2], other.BIRTH_DT)) {
this.BIRTH_DT = data().deepCopy(fields()[2].schema(), other.BIRTH_DT);
fieldSetFlags()[2] = true;
}
if (isValidValue(fields()[3], other.BAL_AMT)) {
this.BAL_AMT = data().deepCopy(fields()[3].schema(), other.BAL_AMT);
fieldSetFlags()[3] = true;
}
}
/**
* Gets the value of the 'KEY_NBR' field.
* @return The value.
*/
public java.lang.CharSequence getKEYNBR() {
return KEY_NBR;
}
public com.modified.User.Builder setKEYNBR(java.lang.CharSequence value) {
validate(fields()[0], value);
this.KEY_NBR = value;
fieldSetFlags()[0] = true;
return this;
}
public boolean hasKEYNBR() {
return fieldSetFlags()[0];
}
public com.modified.User.Builder clearKEYNBR() {
KEY_NBR = null;
fieldSetFlags()[0] = false;
return this;
}
public java.time.Instant getCRTETMS() {
return CRTE_TMS;
}
public com.modified.User.Builder setCRTETMS(java.time.Instant value) {
validate(fields()[1], value);
this.CRTE_TMS = value.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
fieldSetFlags()[1] = true;
return this;
}
public boolean hasCRTETMS() {
return fieldSetFlags()[1];
}
public com.modified.User.Builder clearCRTETMS() {
fieldSetFlags()[1] = false;
return this;
}
public java.time.LocalDate getBIRTHDT() {
return BIRTH_DT;
}
public com.modified.User.Builder setBIRTHDT(java.time.LocalDate value) {
validate(fields()[2], value);
this.BIRTH_DT = value;
fieldSetFlags()[2] = true;
return this;
}
public boolean hasBIRTHDT() {
return fieldSetFlags()[2];
}
public com.modified.User.Builder clearBIRTHDT() {
fieldSetFlags()[2] = false;
return this;
}
/**
* Gets the value of the 'BAL_AMT' field.
* @return The value.
*/
public java.nio.ByteBuffer getBALAMT() {
return BAL_AMT;
}
public com.modified.User.Builder setBALAMT(java.nio.ByteBuffer value) {
validate(fields()[3], value);
this.BAL_AMT = value;
fieldSetFlags()[3] = true;
return this;
}
/**
* Checks whether the 'BAL_AMT' field has been set.
* @return True if the 'BAL_AMT' field has been set, false otherwise.
*/
public boolean hasBALAMT() {
return fieldSetFlags()[3];
}
public com.modified.User.Builder clearBALAMT() {
BAL_AMT = null;
fieldSetFlags()[3] = false;
return this;
}
@Override
@SuppressWarnings("unchecked")
public User build() {
try {
User record = new User();
record.KEY_NBR = fieldSetFlags()[0] ? this.KEY_NBR : (java.lang.CharSequence) defaultValue(fields()[0]);
record.CRTE_TMS = fieldSetFlags()[1] ? this.CRTE_TMS : (java.time.Instant) defaultValue(fields()[1]);
record.BIRTH_DT = fieldSetFlags()[2] ? this.BIRTH_DT : (java.time.LocalDate) defaultValue(fields()[2]);
record.BAL_AMT = fieldSetFlags()[3] ? this.BAL_AMT : (java.nio.ByteBuffer) defaultValue(fields()[3]);
return record;
} catch (org.apache.avro.AvroMissingFieldException e) {
throw e;
} catch (java.lang.Exception e) {
throw new org.apache.avro.AvroRuntimeException(e);
}
}
}
@SuppressWarnings("unchecked")
private static final org.apache.avro.io.DatumWriter<User>
WRITER$ = (org.apache.avro.io.DatumWriter<User>)MODEL$.createDatumWriter(SCHEMA$);
@Override public void writeExternal(java.io.ObjectOutput out)
throws java.io.IOException {
WRITER$.write(this, SpecificData.getEncoder(out));
}
@SuppressWarnings("unchecked")
private static final org.apache.avro.io.DatumReader<User>
READER$ = (org.apache.avro.io.DatumReader<User>)MODEL$.createDatumReader(SCHEMA$);
@Override public void readExternal(java.io.ObjectInput in)
throws java.io.IOException {
READER$.read(this, SpecificData.getDecoder(in));
}
}
我不明白为什么avro要这么做,而且我不喜欢用黑客攻击原始模式来让事情正常进行。有人能帮我弄清楚世界是如何处理这些问题的吗?
注意:这个问题和我原来问的这个问题有关。
1条答案
按热度按时间s4n0splo1#
和我在avro版本1.10.1中得到的行为一样。根据我的经验,avro在反序列化类型union为null的字段和逻辑类型之一(timestamp,decimal)时失败
例子:
{“name”:“costamount”,“type”:[“null”,{“type”:“bytes”,“logicaltype”:“decimal”,“precision”:19,“scale”:2}],“default”:null},