codelipenghui commented on issue #5503: [Schema]GenericData$Record cannot be 
cast 
URL: https://github.com/apache/pulsar/issues/5503#issuecomment-590084502
 
 
   The problem is we should specify the correct namespace and name in the JSON 
definition. I have written a demo in java:
   
   ```java
   package org.apache.pulsar.client.impl;
   
   import org.apache.pulsar.client.api.schema.SchemaDefinition;
   import org.apache.pulsar.client.impl.schema.AvroSchema;
   import org.testng.Assert;
   import org.testng.annotations.Test;
   
   import java.util.Objects;
   
   public class SchemaTest {
   
       @Test
       public void test() {
           SchemaDefinition<User> sd = 
SchemaDefinition.<User>builder().withJsonDef("{\n" +
                   "    \"type\": \"record\",\n" +
                   "    \"name\": \"User\",\n" +
                   "    \"namespace\": 
\"org.apache.pulsar.client.impl.SchemaTest\",\n" +
                   "    \"fields\": [\n" +
                   "      {\n" +
                   "        \"name\": \"id\",\n" +
                   "        \"type\": [\n" +
                   "          \"null\",\n" +
                   "          \"int\"\n" +
                   "        ]\n" +
                   "      },\n" +
                   "      {\n" +
                   "        \"name\": \"name\",\n" +
                   "        \"type\": [\n" +
                   "          \"null\",\n" +
                   "          \"string\"\n" +
                   "        ]\n" +
                   "      }\n" +
                   "    ]\n" +
                   "  }").build();
   
           AvroSchema<User> schema = AvroSchema.of(sd);
           User user = new User();
           user.setId(1);
           user.setName("penghui");
           byte[] encoded = schema.encode(user);
           User decoded = schema.decode(encoded);
           Assert.assertEquals(user, decoded);
       }
   
       private static class User {
           private Integer id;
           private String name;
   
           public Integer getId() {
               return id;
           }
   
           public void setId(Integer id) {
               this.id = id;
           }
   
           public String getName() {
               return name;
           }
   
           public void setName(String name) {
               this.name = name;
           }
   
           @Override
           public boolean equals(Object o) {
               if (this == o) return true;
               if (o == null || getClass() != o.getClass()) return false;
               User user = (User) o;
               return Objects.equals(id, user.id) &&
                       Objects.equals(name, user.name);
           }
   
           @Override
           public int hashCode() {
               return Objects.hash(id, name);
           }
       }
   }
   
   ```
   Avro use full name(`namespace` + "." + `name`) to get Class for decoding 
data. GenericData uses If class not found.  Here is source code of 
`SpecificData` in avro, and `SpecificData` is `GenericData`'s subclass, if the 
class not found, will call `supper.newRecord`, this will introduce 
`GenericRecord`.
   ```
   public Object newRecord(Object old, Schema schema) {
       Class c = getClass(schema);
       if (c == null)
         return super.newRecord(old, schema); // punt to generic
       return (c.isInstance(old) ? old : newInstance(c, schema));
     }
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to