У меня есть Scala 2.12 и я импортировал библиотеку avro4s, следуя ссылке для моего требования.
В основном моя схема avro выглядит следующим образом: Только образец:
Schema: {"name": "person","type": "record","fields": [{"name": "address","type": {"type" : "record","name" : "AddressUSRecord","fields" : [{"name": "streetaddress", "type": "string"},{"name": "city", "type":"string"}]}}]}
Итак, у меня создано 3 класса дел.
Я протестировал схему на основе этих классов, и она отлично выглядит.
Итак, генерация схемы хороша.
Теперь,Я создаю необходимые объекты в соответствии с классом дел.
Когда я пытаюсь записать файл avro, я получаю исключение нулевого указателя.
Ошибка:
Exception in thread "main" java.lang.NullPointerException
at org.apache.avro.util.Utf8$2.toUtf8(Utf8.java:123)
at org.apache.avro.util.Utf8.getBytesFor(Utf8.java:172)
at org.apache.avro.util.Utf8.<init>(Utf8.java:39)
at com.sksamuel.avro4s.Encoder$StringEncoder$.encode(Encoder.scala:73)
at com.sksamuel.avro4s.Encoder$StringEncoder$.encode(Encoder.scala:68)
at com.sksamuel.avro4s.Encoder$.encodeField(Encoder.scala:401)
at com.sksamuel.avro4s.Encoder$.encodeFieldLazy(Encoder.scala:379)
at MyClass$$anon$4$$anon$5.encode(MyClass.scala:90)
at MyClass$$anon$4$$anon$5.encode(MyClass.scala:90)
at com.sksamuel.avro4s.Encoder$.encodeField(Encoder.scala:401)
at com.sksamuel.avro4s.Encoder$.encodeFieldNotLazy(Encoder.scala:373)
at MyClass$$anon$4.encode(MyClass.scala:90)
at MyClass$$anon$4.encode(MyClass.scala:90)
at com.sksamuel.avro4s.AvroDataOutputStream.$anonfun$x$1$2(AvroDataOutputStream.scala:35)
at com.sksamuel.avro4s.AvroDataOutputStream.$anonfun$x$1$2$adapted(AvroDataOutputStream.scala:34)
at com.sksamuel.avro4s.AvroDataOutputStream.write(AvroDataOutputStream.scala:46)
at MyClass$.delayedEndpoint$MyClass$1(MyClass.scala:91)
at MyClass$delayedInit$body.apply(MyClass.scala:42)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:388)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at MyClass$.main(MyClass.scala:42)
at MyClass.main(MyClass.scala)
Код:
//import java.io.File
import com.sksamuel.avro4s.{AvroOutputStream, AvroSchema}
import java.io.File
//case class Person(name: String, age: Int)
//case class Book(title: String, year: Int, owner: Person, authors: Seq[Person])
// case class as per schema
object MyClass extends App {
val outFile = "/path/TestScala.avro"
// val schema = AvroSchema[Book]
println("Hello, World!")
// println(schema)
val head = header(
prop1="val1"
prop2=null
)
val pnlBody = pnlData(
<corresponsing property vlaues, some with null>
)
val record = MyClass(header = head, body = pnlBody)
val schema = AvroSchema[MyClass]
println(schema)
println(record)
val os = AvroOutputStream.data[MyClass].to(new File(outFile)).build(schema)
os.write(record)
os.flush()
os.close()
}
По сути, исходя из имеющейся у меня схемы, я хочу понять, каким должен быть мой конечный объект записи?
ОБНОВЛЕНИЕ :
Исходя из приведенных ниже предложений @Antot и @Daniel, я изменил свой заголовок и класс тела, чтобы использовать Option [String] для всех значений, которые, как ожидается, будут нулевыми.Но все та же проблема.
Изменения в классах дел заголовка и данных, производимых в соответствии со схемой и записью.Правильно ли создана следующая запись?
Пожалуйста, сообщите?
ОБНОВЛЕНИЕ 2:
Я думаю, что проблема с Нуль.Ожидается, что записи будут иметь несколько атрибутов как NULL.Поскольку я изменил на Option [String], его значение должно быть None, а не NULL.Я новичок в Scala, поэтому все еще понимаю его типы данных.
Итак, изменение значения с нуля на None работает.
Однако у меня все еще есть один вопрос.Если мои атрибуты - Option [String], как он переводится в Avro?Если мое значение равно None, переводится ли оно на Avro null?