[ https://issues.apache.org/jira/browse/IGNITE-11909?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sergey Kosarev updated IGNITE-11909: ------------------------------------ Description: Preconditions: 1) AtomicityMode.Transactional 2) Key is custom object. (i.e MyKey) cache.returnAll returns should return Map<MyKey, EntryProcessorResult<T>>, but keys processed on remote node(s) return not unwrapped (as BinaryObject), so we can get a map with mixed keys: {code} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=151593342, hash=31459296, i=2] key.class = MyKey, key = MyKey{i=7} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=405215542, hash=31638042, i=8] key.class = MyKey, key = MyKey{i=1} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=1617838096, hash=31548669, i=5] key.class = MyKey, key = MyKey{i=0} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=138776324, hash=31578460, i=6] key.class = MyKey, key = MyKey{i=9} key.class = MyKey, key = MyKey{i=4} {code} Reproducer : {code} public class CacheEntryProcessorExample2 { /** Cache name. */ private static final String CACHE_NAME = CacheEntryProcessorExample2.class.getSimpleName(); /** Number of keys. */ private static final int KEY_CNT = 10; /** Set of predefined keys. */ private static final Set<MyKey> KEYS_SET; /** * Initializes keys set that is used in bulked operations in the example. */ static { KEYS_SET = new HashSet<>(); for (int i = 0; i < KEY_CNT; i++) KEYS_SET.add(new MyKey(i)); } /** * Executes example. * * @param args Command line arguments, none required. * @throws IgniteException If example execution failed. */ public static void main(String[] args) throws IgniteException { try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { CacheConfiguration<MyKey, Integer> ccfg = new CacheConfiguration<MyKey, Integer>() .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL) .setName(CACHE_NAME); // Auto-close cache at the end of the example. try (IgniteCache<MyKey, Integer> cache = ignite.getOrCreateCache(ccfg)) { Map<MyKey, EntryProcessorResult<Integer>> map = cache.invokeAll(KEYS_SET, (entry, object) -> { System.out.println("entry.key = " + entry.getKey()); return entry.getKey().getI(); }); map.entrySet().forEach( e -> { Object key = e.getKey(); System.out.println("key.class = " + key.getClass().getSimpleName() + ", key = " + key); }); map.entrySet().forEach( e -> { Object key = e.getKey(); if (!(key instanceof MyKey)) { throw new IllegalArgumentException("MyKey expected, but found: " + key.getClass()); } }); } finally { // Distributed cache could be removed from cluster only by #destroyCache() call. ignite.destroyCache(CACHE_NAME); } } } public static class MyKey { private int i; public MyKey() { } public MyKey(int i) { this.i = i; } public int getI() { return i; } public void setI(int i) { this.i = i; } @Override public String toString() { return "MyKey{" + "i=" + i + '}'; } } } {code} was: Preconditions: 1) AtomicityMode.Transactional 2) Key is custom object. (i.e MyKey) cache.returnAll returns should return Map<MyKey, EntryProcessorResult<T>>, but keys processed on remote node(s) are not unwrapped and return as BinaryObject, so we can get a map with mixed keys: {code} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=151593342, hash=31459296, i=2] key.class = MyKey, key = MyKey{i=7} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=405215542, hash=31638042, i=8] key.class = MyKey, key = MyKey{i=1} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=1617838096, hash=31548669, i=5] key.class = MyKey, key = MyKey{i=0} key.class = BinaryObjectImpl, key = org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey [idHash=138776324, hash=31578460, i=6] key.class = MyKey, key = MyKey{i=9} key.class = MyKey, key = MyKey{i=4} {code} Reproducer : {code} public class CacheEntryProcessorExample2 { /** Cache name. */ private static final String CACHE_NAME = CacheEntryProcessorExample2.class.getSimpleName(); /** Number of keys. */ private static final int KEY_CNT = 10; /** Set of predefined keys. */ private static final Set<MyKey> KEYS_SET; /** * Initializes keys set that is used in bulked operations in the example. */ static { KEYS_SET = new HashSet<>(); for (int i = 0; i < KEY_CNT; i++) KEYS_SET.add(new MyKey(i)); } /** * Executes example. * * @param args Command line arguments, none required. * @throws IgniteException If example execution failed. */ public static void main(String[] args) throws IgniteException { try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { CacheConfiguration<MyKey, Integer> ccfg = new CacheConfiguration<MyKey, Integer>() .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL) .setName(CACHE_NAME); // Auto-close cache at the end of the example. try (IgniteCache<MyKey, Integer> cache = ignite.getOrCreateCache(ccfg)) { Map<MyKey, EntryProcessorResult<Integer>> map = cache.invokeAll(KEYS_SET, (entry, object) -> { System.out.println("entry.key = " + entry.getKey()); return entry.getKey().getI(); }); map.entrySet().forEach( e -> { Object key = e.getKey(); System.out.println("key.class = " + key.getClass().getSimpleName() + ", key = " + key); }); map.entrySet().forEach( e -> { Object key = e.getKey(); if (!(key instanceof MyKey)) { throw new IllegalArgumentException("MyKey expected, but found: " + key.getClass()); } }); } finally { // Distributed cache could be removed from cluster only by #destroyCache() call. ignite.destroyCache(CACHE_NAME); } } } public static class MyKey { private int i; public MyKey() { } public MyKey(int i) { this.i = i; } public int getI() { return i; } public void setI(int i) { this.i = i; } @Override public String toString() { return "MyKey{" + "i=" + i + '}'; } } } {code} > Cache.invokeAll() returns a map with BinaryObjects as keys > ---------------------------------------------------------- > > Key: IGNITE-11909 > URL: https://issues.apache.org/jira/browse/IGNITE-11909 > Project: Ignite > Issue Type: Bug > Reporter: Sergey Kosarev > Priority: Major > > Preconditions: > 1) AtomicityMode.Transactional > 2) Key is custom object. (i.e MyKey) > cache.returnAll returns should return Map<MyKey, EntryProcessorResult<T>>, > but keys > processed on remote node(s) return not unwrapped (as BinaryObject), so we can > get a map with mixed keys: > {code} > key.class = BinaryObjectImpl, key = > org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey > [idHash=151593342, hash=31459296, i=2] > key.class = MyKey, key = MyKey{i=7} > key.class = BinaryObjectImpl, key = > org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey > [idHash=405215542, hash=31638042, i=8] > key.class = MyKey, key = MyKey{i=1} > key.class = BinaryObjectImpl, key = > org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey > [idHash=1617838096, hash=31548669, i=5] > key.class = MyKey, key = MyKey{i=0} > key.class = BinaryObjectImpl, key = > org.apache.ignite.examples.datagrid.CacheEntryProcessorExample2$MyKey > [idHash=138776324, hash=31578460, i=6] > key.class = MyKey, key = MyKey{i=9} > key.class = MyKey, key = MyKey{i=4} > {code} > Reproducer : > {code} > public class CacheEntryProcessorExample2 { > /** Cache name. */ > private static final String CACHE_NAME = > CacheEntryProcessorExample2.class.getSimpleName(); > /** Number of keys. */ > private static final int KEY_CNT = 10; > /** Set of predefined keys. */ > private static final Set<MyKey> KEYS_SET; > /** > * Initializes keys set that is used in bulked operations in the example. > */ > static { > KEYS_SET = new HashSet<>(); > for (int i = 0; i < KEY_CNT; i++) > KEYS_SET.add(new MyKey(i)); > } > /** > * Executes example. > * > * @param args Command line arguments, none required. > * @throws IgniteException If example execution failed. > */ > public static void main(String[] args) throws IgniteException { > try (Ignite ignite = > Ignition.start("examples/config/example-ignite.xml")) { > CacheConfiguration<MyKey, Integer> ccfg = new > CacheConfiguration<MyKey, Integer>() > .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL) > .setName(CACHE_NAME); > // Auto-close cache at the end of the example. > try (IgniteCache<MyKey, Integer> cache = > ignite.getOrCreateCache(ccfg)) { > Map<MyKey, EntryProcessorResult<Integer>> map = > cache.invokeAll(KEYS_SET, (entry, object) -> { > System.out.println("entry.key = " + entry.getKey()); > return entry.getKey().getI(); > }); > map.entrySet().forEach( e -> { > Object key = e.getKey(); > System.out.println("key.class = " + > key.getClass().getSimpleName() + ", key = " + key); > }); > map.entrySet().forEach( e -> { > Object key = e.getKey(); > if (!(key instanceof MyKey)) { > throw new IllegalArgumentException("MyKey expected, > but found: " + key.getClass()); > } > }); > } > finally { > // Distributed cache could be removed from cluster only by > #destroyCache() call. > ignite.destroyCache(CACHE_NAME); > } > } > } > public static class MyKey { > private int i; > public MyKey() { > } > public MyKey(int i) { > this.i = i; > } > public int getI() { > return i; > } > public void setI(int i) { > this.i = i; > } > @Override > public String toString() { > return "MyKey{" + > "i=" + i + > '}'; > } > } > } > {code} -- This message was sent by Atlassian JIRA (v7.6.3#76005)