avro-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Scott Carey <scottca...@apache.org>
Subject Re: BigDecimal in Avro
Date Wed, 08 Feb 2012 18:06:39 GMT
You may be able to use the @Stringable annotation.  Avro's reflection is not
that extensible beyond basic types at the moment.  Please file an
enhancement request for BigDecimal support in JIRA.  Thanks!

On 1/18/12 12:34 PM, "Jian Fang" <jian.fang.subscribe@gmail.com> wrote:

> Hi,
> 
> I tried to use Avro 1.6.1 for my existing domain classes with reflection, but
> the BigDecimal type caused some trouble for me.
> 
> Take the following code as an example,
> 
> public class Parent {
> 
>     private String name;
> 
>     private int age;
> 
>     private Date birthday;
> 
>     public String getName() {
>         return name;
>     }
> 
>     public void setName(String name) {
>         this.name <http://this.name>  = name;
>     }
> 
>     public int getAge() {
>         return age;
>     }
> 
>     public void setAge(int age) {
>         this.age = age;
>     }
> 
>     public Date getBirthday() {
>         return birthday;
>     }
> 
>     public void setBirthday(Date birthday) {
>         this.birthday = birthday;
>     }
> }
> 
> public class Child extends Parent {
> 
>     private BigDecimal salary;
> 
>     public BigDecimal getSalary() {
>         return salary;
>     }
> 
>     public void setSalary(BigDecimal salary) {
>         this.salary = salary;
>     }
> }
> 
> I have two classes, the Parent class does not have the BigDecimal type, but
> the Child does have.
> 
> I created a test case as follows:
> 
> public class AvroSchema_UnitTest {
> 
>     @Test
>     public void testBigDecimal() {
>         ReflectData reflectData = ReflectData.AllowNull.get();
>         Schema schema = reflectData.getSchema(Parent.class);
>         System.out.println("Parent");
>         System.out.println(schema.toString());
>         schema = reflectData.getSchema(Child.class);
>         System.out.println("Parent");
>         System.out.println(schema.toString());
>     }
> }
> 
> Run it and here is the following output:
> 
> Parent
> {"type":"record","name":"Parent","namespace":"com.barnesandnoble.domain","fiel
> ds":[{"name":"name","type":["null","string"],"default":null},{"name":"age","ty
> pe":["null","int"],"default":null},{"name":"birthday","type":["null",{"type":"
> record","name":"Date","namespace":"java.util","fields":[]}],"default":null}]}
> 
> org.apache.avro.AvroRuntimeException: java.lang.NoSuchFieldException: SCHEMA$
>     at 
> org.apache.avro.specific.SpecificData.createSchema(SpecificData.java:193)
>     at org.apache.avro.reflect.ReflectData.createSchema(ReflectData.java:249)
>     at 
> org.apache.avro.reflect.ReflectData.createFieldSchema(ReflectData.java:363)
>     at 
> org.apache.avro.reflect.ReflectData$AllowNull.createFieldSchema(ReflectData.ja
> va:68)
>     at org.apache.avro.reflect.ReflectData.createSchema(ReflectData.java:292)
>     at org.apache.avro.specific.SpecificData.getSchema(SpecificData.java:134)
>     at 
> com.barnesandnoble.domain.AvroSchema_UnitTest.testBigDecimal(AvroSchema_UnitTe
> st.java:58)
>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>     at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>     at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.j
> ava:25)
>     at 
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.ja
> va:44)
>     at 
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.jav
> a:15)
>     at 
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java
> :41)
>     at 
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:
> 20)
>     at 
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
> 76)
>     at 
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
> 50)
>     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
>     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
>     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
>     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
>     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
>     at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
>     at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
>     at 
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRun
> ner.java:71)
>     at 
> com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStart
> er.java:199)
>     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>     at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
> Caused by: java.lang.NoSuchFieldException: SCHEMA$
>     at java.lang.Class.getDeclaredField(Class.java:1882)
>     at 
> org.apache.avro.specific.SpecificData.createSchema(SpecificData.java:185)
>     ... 31 more
> 
> As you can see, the Parent class is fine, but the Child class throws an
> exception because of the BigDecimal type.
> 
> Is this a bug? How to get around this if I am not able to change the existing
> domain classes.
> 
> 
> Thanks,
> 
> John
> 
> 
> 
> 
> 
> 



Mime
View raw message