[ 
https://issues.apache.org/jira/browse/IGNITE-2664?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Artem Shutak updated IGNITE-2664:
---------------------------------
    Description: 
{{Cache.invokeAll()}} return a map with {{BinaryObjectImpl}} instead of user 
objects.

Cache.invoke() works fine.

I see a different behavior for Transactional and Atomic caches. But both of 
them return {{BinaryObjectImpl}} instead of user objects at keys/values of a 
result map.

It can be reproduced with 
CacheFullApiNewSelfTest.testInvokeAllOptimisticReadCommitted1() (and others). 
Note: It does not work for plane object and serializable object, but it works 
fine for EXTERNALIZABLE. 

Or use the following code example
{code}
    public static void main(String[] args) throws Exception {
        CacheConfiguration cc = new CacheConfiguration()
            .setMemoryMode(CacheMemoryMode.ONHEAP_TIERED)
            .setCacheMode(CacheMode.PARTITIONED)
            .setAtomicityMode(CacheAtomicityMode.ATOMIC)
            .setLoadPreviousValue(true)
            .setSwapEnabled(true)
            .setCacheStoreFactory(new 
CacheAbstractNewSelfTest.TestStoreFactory())
            
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
            .setAtomicWriteOrderMode(CacheAtomicWriteOrderMode.PRIMARY)
            ;

        cc.setReadThrough(true);
        cc.setWriteThrough(true);

        try(Ignite ignite = Ignition.start(getConfiguration("1"));
            Ignite ignite2 = Ignition.start(getConfiguration("2"));
            Ignite ignite3 = Ignition.start(getConfiguration("3"));
            Ignite ignite4 = Ignition.start(getConfiguration("4"))) {

            System.out.println(ignite.configuration().getMarshaller());

            IgniteCache cache = ignite.getOrCreateCache(cc);

            // Await partition map exchange.
            Thread.sleep(10_000);

            CacheFullApiNewSelfTest.DataMode mode = 
CacheFullApiNewSelfTest.DataMode.SERIALIZABLE;

            final TestObject key = key(1, mode);
            final TestObject val = value(1, mode);

            // InvokeAll
            cache.put(key, val);

            Map<TestObject, EntryProcessorResult<TestObject>> mapRes = 
cache.invokeAll(F.asSet(key), CacheFullApiNewSelfTest.RMV_PROCESSOR);

            for (Map.Entry<TestObject, EntryProcessorResult<TestObject>> e : 
mapRes.entrySet()) {
                TestObject eKey = e.getKey();

                System.out.println(eKey);

                if (!(eKey instanceof TestObject))
                    throw new IllegalStateException("key=" + eKey + ", class=" 
+ eKey.getClass());

                TestObject eVal = e.getValue().get();

                if (!(eVal instanceof TestObject))
                    throw new IllegalStateException("val=" + eVal + ", class=" 
+ eVal.getClass());
            }
        }
    }

    private static IgniteConfiguration getConfiguration(String s) {
        TcpDiscoverySpi spi = new TcpDiscoverySpi();

        TcpDiscoveryMulticastIpFinder finder = new 
TcpDiscoveryMulticastIpFinder();

        finder.setAddresses(Collections.singleton("127.0.0.1:" + 
TcpDiscoverySpi.DFLT_PORT));

        spi.setIpFinder(finder);

        return new IgniteConfiguration()
            .setPeerClassLoadingEnabled(true)
            .setSwapSpaceSpi(new GridTestSwapSpaceSpi())
            .setGridName(s)
            .setDiscoverySpi(spi)
            .setLocalHost("127.0.0.1")
            ;
    }
{code}

I've investigated the issue and found the root cause. Ignite does not unwrap 
BinaryObject before get it to user. See {GridCacheReturn.finishUnmarshal()} and 
org/apache/ignite/internal/processors/cache/GridCacheReturn.java:332. We need 
to pass {{keepBinary}} flag at this place according to used cache.

  was:
{{Cache.invokeAll()}} return a map with {{BinaryObjectImpl}} instead of user 
objects.

Cache.invoke() works fine.

I see a different behavior for Transactional and Atomic caches. But both of 
them return {{BinaryObjectImpl}} instead of user objects at keys/values of a 
result map.

It can be reproduced with 
CacheFullApiNewSelfTest.testInvokeAllOptimisticReadCommitted1() (and others).

Or use the following code example
{code}
    public static void main(String[] args) throws Exception {
        CacheConfiguration cc = new CacheConfiguration()
            .setMemoryMode(CacheMemoryMode.ONHEAP_TIERED)
            .setCacheMode(CacheMode.PARTITIONED)
            .setAtomicityMode(CacheAtomicityMode.ATOMIC)
            .setLoadPreviousValue(true)
            .setSwapEnabled(true)
            .setCacheStoreFactory(new 
CacheAbstractNewSelfTest.TestStoreFactory())
            
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
            .setAtomicWriteOrderMode(CacheAtomicWriteOrderMode.PRIMARY)
            ;

        cc.setReadThrough(true);
        cc.setWriteThrough(true);

        try(Ignite ignite = Ignition.start(getConfiguration("1"));
            Ignite ignite2 = Ignition.start(getConfiguration("2"));
            Ignite ignite3 = Ignition.start(getConfiguration("3"));
            Ignite ignite4 = Ignition.start(getConfiguration("4"))) {

            System.out.println(ignite.configuration().getMarshaller());

            IgniteCache cache = ignite.getOrCreateCache(cc);

            // Await partition map exchange.
            Thread.sleep(10_000);

            CacheFullApiNewSelfTest.DataMode mode = 
CacheFullApiNewSelfTest.DataMode.SERIALIZABLE;

            final TestObject key = key(1, mode);
            final TestObject val = value(1, mode);

            // InvokeAll
            cache.put(key, val);

            Map<TestObject, EntryProcessorResult<TestObject>> mapRes = 
cache.invokeAll(F.asSet(key), CacheFullApiNewSelfTest.RMV_PROCESSOR);

            for (Map.Entry<TestObject, EntryProcessorResult<TestObject>> e : 
mapRes.entrySet()) {
                TestObject eKey = e.getKey();

                System.out.println(eKey);

                if (!(eKey instanceof TestObject))
                    throw new IllegalStateException("key=" + eKey + ", class=" 
+ eKey.getClass());

                TestObject eVal = e.getValue().get();

                if (!(eVal instanceof TestObject))
                    throw new IllegalStateException("val=" + eVal + ", class=" 
+ eVal.getClass());
            }
        }
    }

    private static IgniteConfiguration getConfiguration(String s) {
        TcpDiscoverySpi spi = new TcpDiscoverySpi();

        TcpDiscoveryMulticastIpFinder finder = new 
TcpDiscoveryMulticastIpFinder();

        finder.setAddresses(Collections.singleton("127.0.0.1:" + 
TcpDiscoverySpi.DFLT_PORT));

        spi.setIpFinder(finder);

        return new IgniteConfiguration()
            .setPeerClassLoadingEnabled(true)
            .setSwapSpaceSpi(new GridTestSwapSpaceSpi())
            .setGridName(s)
            .setDiscoverySpi(spi)
            .setLocalHost("127.0.0.1")
            ;
    }
{code}

I've investigated the issue and found the root cause. Ignite does not unwrap 
BinaryObject before get it to user. See {GridCacheReturn.finishUnmarshal()} and 
org/apache/ignite/internal/processors/cache/GridCacheReturn.java:332. We need 
to pass {{keepBinary}} flag at this place according to used cache.


> Cache.invokeAll() returns a map with BinaryObjects instead of user objects
> --------------------------------------------------------------------------
>
>                 Key: IGNITE-2664
>                 URL: https://issues.apache.org/jira/browse/IGNITE-2664
>             Project: Ignite
>          Issue Type: Bug
>    Affects Versions: 1.5.0.final
>            Reporter: Artem Shutak
>            Assignee: Artem Shutak
>             Fix For: 1.6
>
>
> {{Cache.invokeAll()}} return a map with {{BinaryObjectImpl}} instead of user 
> objects.
> Cache.invoke() works fine.
> I see a different behavior for Transactional and Atomic caches. But both of 
> them return {{BinaryObjectImpl}} instead of user objects at keys/values of a 
> result map.
> It can be reproduced with 
> CacheFullApiNewSelfTest.testInvokeAllOptimisticReadCommitted1() (and others). 
> Note: It does not work for plane object and serializable object, but it works 
> fine for EXTERNALIZABLE. 
> Or use the following code example
> {code}
>     public static void main(String[] args) throws Exception {
>         CacheConfiguration cc = new CacheConfiguration()
>             .setMemoryMode(CacheMemoryMode.ONHEAP_TIERED)
>             .setCacheMode(CacheMode.PARTITIONED)
>             .setAtomicityMode(CacheAtomicityMode.ATOMIC)
>             .setLoadPreviousValue(true)
>             .setSwapEnabled(true)
>             .setCacheStoreFactory(new 
> CacheAbstractNewSelfTest.TestStoreFactory())
>             
> .setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
>             .setAtomicWriteOrderMode(CacheAtomicWriteOrderMode.PRIMARY)
>             ;
>         cc.setReadThrough(true);
>         cc.setWriteThrough(true);
>         try(Ignite ignite = Ignition.start(getConfiguration("1"));
>             Ignite ignite2 = Ignition.start(getConfiguration("2"));
>             Ignite ignite3 = Ignition.start(getConfiguration("3"));
>             Ignite ignite4 = Ignition.start(getConfiguration("4"))) {
>             System.out.println(ignite.configuration().getMarshaller());
>             IgniteCache cache = ignite.getOrCreateCache(cc);
>             // Await partition map exchange.
>             Thread.sleep(10_000);
>             CacheFullApiNewSelfTest.DataMode mode = 
> CacheFullApiNewSelfTest.DataMode.SERIALIZABLE;
>             final TestObject key = key(1, mode);
>             final TestObject val = value(1, mode);
>             // InvokeAll
>             cache.put(key, val);
>             Map<TestObject, EntryProcessorResult<TestObject>> mapRes = 
> cache.invokeAll(F.asSet(key), CacheFullApiNewSelfTest.RMV_PROCESSOR);
>             for (Map.Entry<TestObject, EntryProcessorResult<TestObject>> e : 
> mapRes.entrySet()) {
>                 TestObject eKey = e.getKey();
>                 System.out.println(eKey);
>                 if (!(eKey instanceof TestObject))
>                     throw new IllegalStateException("key=" + eKey + ", 
> class=" + eKey.getClass());
>                 TestObject eVal = e.getValue().get();
>                 if (!(eVal instanceof TestObject))
>                     throw new IllegalStateException("val=" + eVal + ", 
> class=" + eVal.getClass());
>             }
>         }
>     }
>     private static IgniteConfiguration getConfiguration(String s) {
>         TcpDiscoverySpi spi = new TcpDiscoverySpi();
>         TcpDiscoveryMulticastIpFinder finder = new 
> TcpDiscoveryMulticastIpFinder();
>         finder.setAddresses(Collections.singleton("127.0.0.1:" + 
> TcpDiscoverySpi.DFLT_PORT));
>         spi.setIpFinder(finder);
>         return new IgniteConfiguration()
>             .setPeerClassLoadingEnabled(true)
>             .setSwapSpaceSpi(new GridTestSwapSpaceSpi())
>             .setGridName(s)
>             .setDiscoverySpi(spi)
>             .setLocalHost("127.0.0.1")
>             ;
>     }
> {code}
> I've investigated the issue and found the root cause. Ignite does not unwrap 
> BinaryObject before get it to user. See {GridCacheReturn.finishUnmarshal()} 
> and org/apache/ignite/internal/processors/cache/GridCacheReturn.java:332. We 
> need to pass {{keepBinary}} flag at this place according to used cache.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to