Bojidar Marinov created IGNITE-13563: ----------------------------------------
Summary: Deserializing IBinaryObject containing an IBinaryObject field fails Key: IGNITE-13563 URL: https://issues.apache.org/jira/browse/IGNITE-13563 Project: Ignite Issue Type: Bug Components: binary, platforms Affects Versions: 2.8.1 Environment: Arch Linux (updated Oct 5): Linux 5.8.12, DotNet 3.1.108, OpenJDK 1.8.0_265. Reporter: Bojidar Marinov Attachments: 0001-Fix-IBinaryObject-Deserialize.patch, Program.cs When one has a data object which has an IBinaryObject property, like so: {code:c#} class Model { public IBinaryObject Value { get; set; } } {code} .. and proceeds to fill that property with an IBinaryObject of an unknown type (e.g. a binary object from a cache that has WithKeepBinary on): {code:c#} var binary = ignite.GetBinary(); var model = new Model { Value = binary.GetBuilder("nonexistent").Build() }; {code} Then, the resulting object is savable/loadable from caches, as expected: {code:c#} var cache = ignite.GetOrCreateCache<string, Model>("models"); cache.Put("model", model); var modelFromCache = cache.Get("model"); // Equivalent to model {code} However, trying to convert the object to IBinaryObject (using ToBinary) and then deserializing that manually fails: {code:c#} var binaryObject = binary.ToBinary<IBinaryObject>(model); var modelFromBinary = binaryObject.Deserialize<Model>(); // Unknown pair [platformId=1, typeId=486454369] {code} I have attached a program which reproduces the issue. ---- After investigating the issue, it seems to occur because {{BinaryObject.Deserialize<T>()}} uses {{BinaryMode.Deserialize}}. This, in turn, causes {{BinaryReader.ReadBinaryObject()}} to call {{BinaryReader.Deserialize()}} for the first {{BinaryTypeId.Binary}} object found (while switching to {{BinaryMode.KeepBinary}} for nested objects). Then, {{BinaryReader.ReadFullObject()}} gets called, and not knowing better, tries to deserialize the object of a nonexistent type. Now, {{BinaryMode.Deserialize}} is also used by {{CacheClient}}. However, upon further investigation of the values passed to {{Marshaller.Unmarshall}}, {{CacheClient}} unmarshalls values starting with {{BinaryTypeId.Binary}}, while {{BinaryObject}} unmarshalls values starting directly with {{BinaryUtils.HdrFull}}; thus, {{BinaryReader}} functions correctly for caches but fails with binary objects. Due to the this, I think the proper fix would be to change {{BinaryObject.Deserialize<T>()}} to use {{BinaryMode.KeepBinary}}. I have attached a patch file containing that fix and an accompanying test. -- This message was sent by Atlassian Jira (v8.3.4#803005)