Avro Tools Version - 1.9.2
This is the problem that I am facing while deserializing Avro data. Looks like Avro is not able to generate correct POJO class when field is Union with nulls and logical types.
Current Behavior: When avro schema has a fields that is union of null and logical type. Avro do not add conversion type array thus we get class cast exceptions. This is the problem with original.avsc
Expected behavior: Avro should be able to serialize logical types having nulls.
Take a look at the below original.avsc, There are no conversions
array created for any of the fields. Which results in ClassCastException
since original field data is in primitive type and POJO field is based on logical type.
original.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
}
]
}
POJO based on Original.avsc
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));
}
}
Whereas, If I modify the original schema and take out null values from logical type fields. Avro generates proper conversions
(check highlighted part) for the logical type fields and I am able to successfully deserialize the avro message to POJO.
modified.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
}
]
}
Generated POJO class from modified schema
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));
}
}
I am not understanding why Avro is doing this and I do not feel comfortable with hacking original schema to make things work. Can someone please help me to figure out how the world is handling these issues?
Note: This question is related to this original question that I have asked.