jxcd opened a new issue, #10846:
URL: https://github.com/apache/ignite/issues/10846

   I have  a class
   
   ```java
   public record Coordinate(
           Integer id,
           Integer x,
           Integer y,
           Integer z
   ) {}
   ```
   
   It will report an exception when using when use `cache.get(key)` , the cache 
type is `org.apache.ignite.IgniteCache<String, Object> cache`
   exception is:
   ```
   Caused by: class org.apache.ignite.binary.BinaryObjectException: Failed to 
deserialize object [typeName=com.me.boot.dataignite.boot.dto.Coordinate]
   Caused by: class org.apache.ignite.binary.BinaryObjectException: Failed to 
read field [name=id]
   Caused by: class org.apache.ignite.binary.BinaryObjectException: Failed to 
set value for field: private final java.lang.Integer 
com.me.boot.dataignite.boot.dto.Coordinate.id
   Caused by: java.lang.IllegalAccessException: Can not set final 
java.lang.Integer field com.me.boot.dataignite.boot.dto.Coordinate.id to 
java.lang.Integer
   ```
   
   then when I debug, find 
`org.apache.ignite.internal.binary.BinaryClassDescriptor#read`, in `switch 
(mode) case OBJECT:`:
   The process of deserialization is to use `res = newInstance()` create res 
first, and then in `info.read(res, reader)` use `field.set(obj, val)` set field 
value, **but when Field is final, an exception will be throws**
   
   For the Record class, I currently add a piece of code to solve the 
deserialization problem:
   
   ```java
                   case OBJECT:
                       if (Record.class.isAssignableFrom(cls)) {
                           // the record class default has All-args constructor
                           // read all field value to Object[] values
                           Object[] values = new Object[fields.length];
                           for (int i = 0; i < fields.length; i++) {
                               BinaryFieldAccessor fieldAccessor = fields[i];
                               Object val = reader.readField(fieldAccessor.id);
                               values[i] = val;
                           }
                           // invoke All-args constructor to create res
                           Constructor<?> constructor = 
cls.getDeclaredConstructors()[0];
                           res = constructor.newInstance(values);
                       } else {
                           res = newInstance();
                           reader.setHandle(res);
                           for (BinaryFieldAccessor info : fields)
                               info.read(res, reader);
                       }
                       break;
   ```
   
   But besides this way, is there any other way? 
   
   - like only `@Override 
org.apache.ignite.internal.binary.BinaryClassDescriptor#read` and use it, no 
need to modify dependent source code
   - like set BinaryConfiguration,  but `setSerializer(BinarySerializer 
serializer)` doesn't seem to work
   
   
   


-- 
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.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to