IGNITE-51 Copy object value and key when are passed in EntryProcessor. Added 
tests.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/00e03889
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/00e03889
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/00e03889

Branch: refs/heads/ignite-user-req
Commit: 00e03889feeafbdead41f9137e659f9b397f853b
Parents: 43c04a0
Author: nikolay_tikhonov <ntikho...@gridgain.com>
Authored: Wed Mar 4 15:49:25 2015 +0300
Committer: nikolay_tikhonov <ntikho...@gridgain.com>
Committed: Wed Mar 4 17:14:08 2015 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       |   1 +
 .../processors/cache/CacheInvokeEntry.java      |  45 +-
 .../processors/cache/CacheLazyEntry.java        |  38 +-
 .../processors/cache/GridCacheMapEntry.java     |  44 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |   5 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  39 +-
 .../local/atomic/GridLocalAtomicCache.java      |  24 +-
 .../cache/transactions/IgniteTxAdapter.java     |   5 +-
 .../cache/transactions/IgniteTxEntry.java       |   3 +-
 .../transactions/IgniteTxLocalAdapter.java      |  15 +-
 .../cache/GridCacheOnFlagAbstractSelfTest.java  | 553 +++++++++++++++++++
 .../cache/GridCacheOnFlagAtomicSelfTest.java    |  39 ++
 .../cache/GridCacheOnFlagLocalSelfTest.java     |  39 ++
 .../GridCacheOnFlagReplicatedSelfTest.java      |  39 ++
 .../GridCacheOnFlagTxPartitionedSelfTest.java   |  39 ++
 15 files changed, 792 insertions(+), 136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
 
b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 21d008c..96530c4 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -355,6 +355,7 @@ public class CacheConfiguration<K, V> extends 
MutableConfiguration<K, V> {
         cacheLoaderFactory = cc.getCacheLoaderFactory();
         cacheMode = cc.getCacheMode();
         cacheWriterFactory = cc.getCacheWriterFactory();
+        cpOnGet = cc.isCopyOnGet();
         dfltLockTimeout = cc.getDefaultLockTimeout();
         dfltQryTimeout = cc.getDefaultQueryTimeout();
         distro = cc.getDistributionMode();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeEntry.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeEntry.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeEntry.java
index 3ef7e6d..d87cd3e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeEntry.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeEntry.java
@@ -18,27 +18,14 @@
 package org.apache.ignite.internal.processors.cache;
 
 import org.apache.ignite.*;
-import org.apache.ignite.internal.util.tostring.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
-import org.jetbrains.annotations.*;
 
 import javax.cache.processor.*;
 
 /**
  * Implementation of {@link MutableEntry} passed to the {@link 
EntryProcessor#process(MutableEntry, Object...)}.
  */
-public class CacheInvokeEntry<K, V> implements MutableEntry<K, V> {
-    /** */
-    private final GridCacheContext cctx;
-
-    /** */
-    @GridToStringInclude
-    private final K key;
-
-    /** */
-    @GridToStringInclude
-    private V val;
-
+public class CacheInvokeEntry<K, V> extends CacheLazyEntry<K, V> implements 
MutableEntry<K, V> {
     /** */
     private final boolean hadVal;
 
@@ -46,29 +33,25 @@ public class CacheInvokeEntry<K, V> implements 
MutableEntry<K, V> {
     private Operation op = Operation.NONE;
 
     /**
-     * @param cctx Cache context.
-     * @param key Key.
-     * @param val Value.
+     * @param cctx   Cache context.
+     * @param keyObj Key cache object.
+     * @param valObj Cache object value.
      */
-    public CacheInvokeEntry(GridCacheContext cctx, K key, @Nullable V val) {
-        assert cctx != null;
-        assert key != null;
-
-        this.cctx = cctx;
-        this.key = key;
-        this.val = val;
+    public CacheInvokeEntry(GridCacheContext cctx, KeyCacheObject keyObj, 
CacheObject valObj) {
+        super(cctx, keyObj, valObj);
 
-        hadVal = val != null;
+        this.hadVal = getValue() != null;
     }
 
     /** {@inheritDoc} */
     @Override public boolean exists() {
-        return val != null;
+        return getValue() != null;
     }
 
     /** {@inheritDoc} */
     @Override public void remove() {
         val = null;
+        valObj = null;
 
         if (op == Operation.CREATE)
             op = Operation.NONE;
@@ -87,16 +70,6 @@ public class CacheInvokeEntry<K, V> implements 
MutableEntry<K, V> {
     }
 
     /** {@inheritDoc} */
-    @Override public K getKey() {
-        return key;
-    }
-
-    /** {@inheritDoc} */
-    @Override public V getValue() {
-        return val;
-    }
-
-    /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public <T> T unwrap(Class<T> cls) {
         if (cls.isAssignableFrom(Ignite.class))

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLazyEntry.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLazyEntry.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLazyEntry.java
index 7b696ec..29d04ce 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLazyEntry.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLazyEntry.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import org.apache.ignite.internal.util.tostring.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 
 import javax.cache.*;
@@ -26,56 +27,41 @@ import javax.cache.*;
  */
 public class CacheLazyEntry<K, V> implements Cache.Entry<K, V> {
     /** Cache context. */
-    private GridCacheContext<K, V> cctx;
+    protected GridCacheContext cctx;
 
     /** Key cache object. */
-    private KeyCacheObject keyObj;
+    protected KeyCacheObject keyObj;
 
     /** Cache object value. */
-    private CacheObject valObj;
+    protected CacheObject valObj;
 
     /** Key. */
-    private K key;
+    @GridToStringInclude
+    protected K key;
 
     /** Value. */
-    private V val;
+    @GridToStringInclude
+    protected V val;
 
     /**
+     * @param cctx Cache context.
      * @param keyObj Key cache object.
      * @param valObj Cache object value.
-     * @param cctx Cache context.
      */
-    public CacheLazyEntry(KeyCacheObject keyObj, CacheObject valObj, 
GridCacheContext<K, V> cctx) {
+    public CacheLazyEntry(GridCacheContext cctx, KeyCacheObject keyObj, 
CacheObject valObj) {
         this.keyObj = keyObj;
         this.valObj = valObj;
         this.cctx = cctx;
     }
 
     /**
-     * @param key Key.
-     * @param val Value.
-     */
-    public CacheLazyEntry(K key, V val) {
-        this.key = key;
-        this.val = val;
-    }
-
-    /**
      * @param keyObj Key cache object.
-     * @param valObj Cache object value.
-     * @param key Key.
      * @param val Value.
      * @param cctx Cache context.
      */
-    public CacheLazyEntry(KeyCacheObject keyObj,
-        CacheObject valObj,
-        K key,
-        V val, 
-        GridCacheContext<K, V> cctx) {
+    public CacheLazyEntry(GridCacheContext cctx, KeyCacheObject keyObj, V val) 
{
         this.keyObj = keyObj;
-        this.valObj = valObj;
         this.val = val;
-        this.key = key;
         this.cctx = cctx;
     }
 
@@ -106,6 +92,6 @@ public class CacheLazyEntry<K, V> implements Cache.Entry<K, 
V> {
 
     /** {@inheritDoc} */
     public String toString() {
-        return "CacheEntry [key=" + getKey() + ", val=" + getValue() + ']';
+        return S.toString(CacheLazyEntry.class, this);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 0b7b0df..18fc3ed 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -1031,7 +1031,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
             if (intercept) {
                 val0 = CU.value(val, cctx, true);
 
-                Object interceptorVal = 
cctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(key, old, cctx),
+                Object interceptorVal = 
cctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(cctx, key, old),
                     val0);
 
                 if (interceptorVal == null)
@@ -1114,7 +1114,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
             cctx.store().putToStore(tx, key, val, newVer);
 
         if (intercept)
-            cctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(key, 
val, cctx));
+            cctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(cctx, 
key, val));
 
         return valid ? new GridCacheUpdateTxResult(true, retval ? old : null) :
             new GridCacheUpdateTxResult(false, null);
@@ -1177,7 +1177,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
             old = (retval || intercept) ? rawGetOrUnmarshalUnlocked(!retval) : 
val;
 
             if (intercept) {
-                entry0 = new CacheLazyEntry(key, old, cctx);
+                entry0 = new CacheLazyEntry(cctx, key, old);
 
                 interceptRes = 
cctx.config().getInterceptor().onBeforeRemove(entry0);
 
@@ -1406,7 +1406,6 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
 
             CacheObject updated;
 
-            Object key0 = null;
             Object updated0 = null;
 
             // Calculate new value.
@@ -1417,10 +1416,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
 
                 assert entryProcessor != null;
 
-                key0 = key.value(cctx, false);
-                old0 = value(old0, old, false);
-
-                CacheInvokeEntry<Object, Object> entry = new 
CacheInvokeEntry<>(cctx, key0, old0);
+                CacheInvokeEntry<Object, Object> entry = new 
CacheInvokeEntry<>(cctx, key, old);
 
                 try {
                     Object computed = entryProcessor.process(entry, 
invokeArgs);
@@ -1459,7 +1455,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
                     old0 = value(old0, old, false);
 
                     Object interceptorVal = cctx.config().getInterceptor()
-                        .onBeforePut(new CacheLazyEntry(key, old, key0, old0, 
cctx), updated0);
+                        .onBeforePut(new CacheLazyEntry(cctx, key, old), 
updated0);
 
                     if (interceptorVal == null)
                         return new GridTuple3<>(false, 
cctx.unwrapTemporary(old0), invokeRes);
@@ -1471,7 +1467,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
                 }
                 else {
                     interceptorRes = cctx.config().getInterceptor()
-                        .onBeforeRemove(new CacheLazyEntry(key, old, key0, 
old0, cctx));
+                        .onBeforeRemove(new CacheLazyEntry(cctx, key, old));
 
                     if (cctx.cancelRemove(interceptorRes))
                         return new GridTuple3<>(false, 
cctx.unwrapTemporary(interceptorRes.get2()), invokeRes);
@@ -1582,9 +1578,9 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
 
             if (intercept) {
                 if (op == GridCacheOperation.UPDATE)
-                    cctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(key, null, key0, updated0, cctx));
+                    cctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(cctx, key, updated));
                 else
-                    cctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(key, old, key0, old0, cctx));
+                    cctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(cctx, key, old));
             }
         }
 
@@ -1850,8 +1846,6 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
                 }
             }
 
-            Object key0 = null;
-
             // Calculate new value in case we met transform.
             if (op == GridCacheOperation.TRANSFORM) {
                 assert conflictCtx == null : "Cannot be TRANSFORM here if 
conflict resolution was performed earlier.";
@@ -1860,18 +1854,15 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
 
                 EntryProcessor<Object, Object, ?> entryProcessor = 
(EntryProcessor<Object, Object, ?>)writeObj;
 
-                key0 = key.value(cctx, false);
-                old0 = value(old0, oldVal, false);
-
-                CacheInvokeEntry<Object, Object> entry = new 
CacheInvokeEntry<>(cctx, key0, old0);
+                CacheInvokeEntry<Object, Object> entry = new 
CacheInvokeEntry(cctx, key, oldVal);
 
                 try {
                     Object computed = entryProcessor.process(entry, 
invokeArgs);
 
-                    updated0 = cctx.unwrapTemporary(entry.getValue());
-
-                    if (entry.modified())
+                    if (entry.modified()) {
                         updated = cctx.toCacheObject(updated0);
+                        updated0 = cctx.unwrapTemporary(entry.getValue());
+                    }
                     else
                         updated = oldVal;
 
@@ -1986,8 +1977,8 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
                 if (intercept) {
                     updated0 = value(updated0, updated, false);
 
-                    Object interceptorVal = 
cctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(key, oldVal,
-                        key0, old0, cctx), updated0);
+                    Object interceptorVal = cctx.config().getInterceptor()
+                        .onBeforePut(new CacheLazyEntry(cctx, key, oldVal), 
updated0);
 
                     if (interceptorVal == null)
                         return new GridCacheUpdateAtomicResult(false,
@@ -2062,8 +2053,7 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
             }
             else {
                 if (intercept) {
-                    interceptRes = 
cctx.config().getInterceptor().onBeforeRemove(new CacheLazyEntry(key, oldVal, 
key0,
-                        old0, cctx));
+                    interceptRes = 
cctx.config().getInterceptor().onBeforeRemove(new CacheLazyEntry(cctx, key, 
oldVal));
 
                     if (cctx.cancelRemove(interceptRes))
                         return new GridCacheUpdateAtomicResult(false,
@@ -2159,9 +2149,9 @@ public abstract class GridCacheMapEntry implements 
GridCacheEntryEx {
 
             if (intercept) {
                 if (op == GridCacheOperation.UPDATE)
-                    cctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(key, null, key0, updated0, cctx));
+                    cctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(cctx, key, updated));
                 else
-                    cctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(key, oldVal, null, old0, cctx));
+                    cctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(cctx, key, oldVal));
 
                 if (interceptRes != null)
                     oldVal = 
cctx.toCacheObject(cctx.unwrapTemporary(interceptRes.get2()));

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 11101fe..14bcc13 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -318,13 +318,10 @@ public final class GridDhtTxPrepareFuture<K, V> extends 
GridCompoundIdentityFutu
                             Object procRes = null;
                             Exception err = null;
 
-                            Object keyVal = key.value(cacheCtx, false);
-                            Object val0 = CU.value(val, cacheCtx, false);
-
                             for (T2<EntryProcessor<Object, Object, Object>, 
Object[]> t : txEntry.entryProcessors()) {
                                 try {
                                     CacheInvokeEntry<Object, Object> 
invokeEntry =
-                                        new 
CacheInvokeEntry<>(txEntry.context(), keyVal, val0);
+                                        new 
CacheInvokeEntry<>(txEntry.context(), key, val);
 
                                     EntryProcessor<Object, Object, Object> 
processor = t.get1();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index 8d7b390..994b55e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -1334,13 +1334,9 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                         taskName,
                         null);
 
-                    Object keyVal = entry.key().value(ctx, false);
-                    Object oldVal = CU.value(old, ctx, false);
                     Object updatedVal = null;
 
-                    CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(ctx,
-                        keyVal,
-                        oldVal);
+                    CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry(ctx, entry.key(), old);
 
                     CacheObject updated;
                     CacheInvokeDirectResult invokeRes = null;
@@ -1348,9 +1344,16 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                     try {
                         Object computed = entryProcessor.process(invokeEntry, 
req.invokeArguments());
 
-                        updatedVal = 
ctx.unwrapTemporary(invokeEntry.getValue());
+                        if (invokeEntry.modified()) {
+                            updatedVal = 
ctx.unwrapTemporary(invokeEntry.getValue());
 
-                        updated = ctx.toCacheObject(updatedVal);
+                            updated = ctx.toCacheObject(updatedVal);
+                        }
+                        else {
+                            updated = old;
+
+                            updatedVal = CU.value(old, ctx, true);
+                        }
 
                         if (computed != null)
                             invokeRes = new 
CacheInvokeDirectResult(entry.key(),
@@ -1368,7 +1371,7 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                     if (updated == null) {
                         if (intercept) {
                             IgniteBiTuple<Boolean, ?> interceptorRes = 
ctx.config().getInterceptor().onBeforeRemove(
-                                new CacheEntryImpl(keyVal, oldVal));
+                                new CacheLazyEntry(ctx, entry.key(), old));
 
                             if (ctx.cancelRemove(interceptorRes))
                                 continue;
@@ -1410,8 +1413,8 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                     }
                     else {
                         if (intercept) {
-                            Object val = 
ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(keyVal, oldVal),
-                                updatedVal);
+                            Object val = ctx.config().getInterceptor()
+                                .onBeforePut(new CacheLazyEntry(ctx, 
entry.key(), old), updatedVal);
 
                             if (val == null)
                                 continue;
@@ -1476,10 +1479,8 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                             taskName,
                             null);
 
-                        Object val = 
ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(
-                            entry.key(),
-                            old,
-                            ctx),
+                        Object val = 
ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(ctx, entry.key(),
+                            old),
                             updated.value(ctx, false));
 
                         if (val == null)
@@ -1514,7 +1515,7 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                             null);
 
                         IgniteBiTuple<Boolean, ?> interceptorRes = 
ctx.config().getInterceptor()
-                            .onBeforeRemove(new CacheLazyEntry(entry.key(), 
old, ctx));
+                            .onBeforeRemove(new CacheLazyEntry(ctx, 
entry.key(), old));
 
                         if (ctx.cancelRemove(interceptorRes))
                             continue;
@@ -1983,16 +1984,16 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                     if (intercept) {
                         if (op == UPDATE) {
                             ctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(
+                                ctx, 
                                 entry.key(),
-                                updRes.newValue(),
-                                ctx));
+                                updRes.newValue()));
                         }
                         else {
                             assert op == DELETE : op;
 
                             // Old value should be already loaded for 
'CacheInterceptor.onBeforeRemove'.
-                            ctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(entry.key(), 
-                                updRes.oldValue(), ctx));
+                            ctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(ctx, entry.key(),
+                                updRes.oldValue()));
                         }
                     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
index d7ad717..7929e37 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
@@ -1178,7 +1178,7 @@ public class GridLocalAtomicCache<K, V> extends 
GridCacheAdapter<K, V> {
                         Object keyVal = entry.key().value(ctx, false);
                         Object oldVal = CU.value(old, ctx, false);
 
-                        CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(ctx, keyVal, oldVal);
+                        CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(ctx, entry.key(), old);
 
                         CacheObject updated;
                         Object updatedVal = null;
@@ -1187,9 +1187,16 @@ public class GridLocalAtomicCache<K, V> extends 
GridCacheAdapter<K, V> {
                         try {
                             Object computed = 
entryProcessor.process(invokeEntry, invokeArgs);
 
-                            updatedVal = 
ctx.unwrapTemporary(invokeEntry.getValue());
+                            if (invokeEntry.modified()) {
+                                updatedVal = 
ctx.unwrapTemporary(invokeEntry.getValue());
 
-                            updated = ctx.toCacheObject(updatedVal);
+                                updated = ctx.toCacheObject(updatedVal);
+                            }
+                            else {
+                                updatedVal = oldVal;
+
+                                updated = old;
+                            }
 
                             if (computed != null)
                                 invokeRes = new 
CacheInvokeResult<>(ctx.unwrapTemporary(computed));
@@ -1238,7 +1245,7 @@ public class GridLocalAtomicCache<K, V> extends 
GridCacheAdapter<K, V> {
                         else {
                             if (intercept) {
                                 Object interceptorVal = 
ctx.config().getInterceptor()
-                                    .onBeforePut(new CacheLazyEntry(keyVal, 
oldVal), updatedVal);
+                                    .onBeforePut(new CacheLazyEntry(ctx, 
entry.key(), old), updatedVal);
 
                                 if (interceptorVal == null)
                                     continue;
@@ -1287,7 +1294,7 @@ public class GridLocalAtomicCache<K, V> extends 
GridCacheAdapter<K, V> {
                                 null);
 
                             Object interceptorVal = 
ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(
-                                entry.key(), old, ctx), val);
+                                ctx, entry.key(), old), val);
 
                             if (interceptorVal == null)
                                 continue;
@@ -1318,7 +1325,7 @@ public class GridLocalAtomicCache<K, V> extends 
GridCacheAdapter<K, V> {
                                 null);
 
                             IgniteBiTuple<Boolean, ?> interceptorRes = 
ctx.config().getInterceptor()
-                                .onBeforeRemove(new 
CacheLazyEntry(entry.key(), old, ctx));
+                                .onBeforeRemove(new CacheLazyEntry(ctx, 
entry.key(), old));
 
                             if (ctx.cancelRemove(interceptorRes))
                                 continue;
@@ -1466,10 +1473,9 @@ public class GridLocalAtomicCache<K, V> extends 
GridCacheAdapter<K, V> {
 
                 if (intercept) {
                     if (op == UPDATE)
-                        ctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(entry.key(), writeVal, ctx));
+                        ctx.config().getInterceptor().onAfterPut(new 
CacheLazyEntry(ctx, entry.key(), writeVal));
                     else
-                        ctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(entry.key(), null, null,
-                            t.get2(), ctx));
+                        ctx.config().getInterceptor().onAfterRemove(new 
CacheLazyEntry(ctx, entry.key(), t.get2()));
                 }
             }
             catch (GridCacheEntryRemovedException ignore) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 1cd4521..f618b4a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -1225,12 +1225,11 @@ public abstract class IgniteTxAdapter extends 
GridMetadataAwareAdapter
 
                 boolean modified = false;
 
-                Object key = txEntry.key().value(txEntry.context(), false);
-
                 Object val = CU.value(cacheVal, txEntry.context(), false);
 
                 for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : 
txEntry.entryProcessors()) {
-                    CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(txEntry.context(), key, val);
+                    CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(txEntry.context(), 
+                        txEntry.key(), cacheVal);
 
                     try {
                         EntryProcessor<Object, Object, Object> processor = 
t.get1();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
index db166fb..e4ac3d2 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
@@ -553,12 +553,11 @@ public class IgniteTxEntry implements 
GridPeerDeployAware, Externalizable, Optim
      */
     @SuppressWarnings("unchecked")
     public CacheObject applyEntryProcessors(CacheObject cacheVal) {
-        Object key = CU.value(this.key, ctx, false);
         Object val = CU.value(cacheVal, ctx, false);
 
         for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : 
entryProcessors()) {
             try {
-                CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(ctx, key, val);
+                CacheInvokeEntry<Object, Object> invokeEntry = new 
CacheInvokeEntry<>(ctx, key, cacheVal);
 
                 EntryProcessor processor = t.get1();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index efc3c06..b6c62b7 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -538,7 +538,7 @@ public abstract class IgniteTxLocalAdapter extends 
IgniteTxAdapter
                             if (intercept) {
                                 Object interceptorVal = 
cacheCtx.config().getInterceptor()
                                     .onBeforePut(new CacheLazyEntry(
-                                        key, 
e.cached().rawGetOrUnmarshal(true), cacheCtx),
+                                        cacheCtx, key, 
e.cached().rawGetOrUnmarshal(true)),
                                         CU.value(val, cacheCtx, false));
 
                                 if (interceptorVal == null)
@@ -577,12 +577,10 @@ public abstract class IgniteTxLocalAdapter extends 
IgniteTxAdapter
                             }
 
                             if (intercept) {
-                                Object oldVal = 
CU.value(e.cached().rawGetOrUnmarshal(true), cacheCtx, false);
-
                                 IgniteBiTuple<Boolean, Object> t = 
cacheCtx.config().getInterceptor()
-                                    .onBeforeRemove(new CacheLazyEntry(key,
-                                        e.cached().rawGetOrUnmarshal(true),
-                                        cacheCtx));
+                                    .onBeforeRemove(new 
CacheLazyEntry(cacheCtx, 
+                                        key,
+                                        e.cached().rawGetOrUnmarshal(true)));
 
                                 if (cacheCtx.cancelRemove(t))
                                     continue;
@@ -2464,20 +2462,17 @@ public abstract class IgniteTxLocalAdapter extends 
IgniteTxAdapter
         GridCacheContext ctx = txEntry.context();
 
         Object keyVal = txEntry.key().value(ctx, false);
-        Object val = CU.value(cacheVal, ctx, false);
 
         try {
             Object res = null;
 
             for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : 
txEntry.entryProcessors()) {
                 CacheInvokeEntry<Object, Object> invokeEntry =
-                    new CacheInvokeEntry<>(txEntry.context(), keyVal, val);
+                    new CacheInvokeEntry<>(txEntry.context(), txEntry.key(), 
cacheVal);
 
                 EntryProcessor<Object, Object, ?> entryProcessor = t.get1();
 
                 res = entryProcessor.process(invokeEntry, t.get2());
-
-                val = invokeEntry.getValue();
             }
 
             if (res != null)

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAbstractSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAbstractSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAbstractSelfTest.java
new file mode 100644
index 0000000..c486efe
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAbstractSelfTest.java
@@ -0,0 +1,553 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.jetbrains.annotations.*;
+
+import javax.cache.*;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.MutableEntry;
+import java.io.*;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Tests {@link org.apache.ignite.cache.CacheInterceptor}.
+ */
+public abstract class GridCacheOnFlagAbstractSelfTest extends 
GridCacheAbstractSelfTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    public static final int ITER_CNT = 1000;
+
+    /** */
+    public static final int WRONG_VALUE = -999999;
+
+    /** */
+    private static Interceptor interceptor;
+
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return 1;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        interceptor = new Interceptor();
+
+        super.beforeTestsStarted();
+
+        awaitPartitionMapExchange();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        interceptor = new Interceptor();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration c = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(IP_FINDER);
+
+        c.setDiscoverySpi(spi);
+
+        c.getTransactionConfiguration().setTxSerializableEnabled(true);
+
+        return c;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration cacheConfiguration(String gridName) 
throws Exception {
+        CacheConfiguration ccfg = super.cacheConfiguration(gridName);
+
+        assertNotNull(interceptor);
+
+        ccfg.setInterceptor(interceptor);
+        
+        ccfg.setAtomicityMode(atomicityMode());
+        ccfg.setDistributionMode(distributionMode());
+        ccfg.setCacheMode(cacheMode());
+
+        return ccfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected abstract CacheAtomicityMode atomicityMode();
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testInterceptor() throws Exception {
+        IgniteCache<TestKey, TestValue> cache = grid(0).jcache(null);
+
+        for (int i = 0; i < ITER_CNT; i++) {
+            final TestValue val = new TestValue(i);
+            final TestKey key = new TestKey(i, i);
+
+            interceptor.delegate(new CacheInterceptorAdapter<TestKey, 
TestValue>() {
+                @Override public void onAfterPut(Cache.Entry<TestKey, 
TestValue> entry) {
+                    assertNotSame(key, entry.getKey());
+                    assertNotSame(val, entry.getValue());
+
+                    assertSame(entry.getValue(), entry.getValue());
+                    assertSame(entry.getKey(), entry.getKey());
+
+                    // Try change key and value.
+                    entry.getKey().field(WRONG_VALUE);
+                    entry.getValue().val(WRONG_VALUE);
+                }
+            });
+
+            cache.put(key, val);
+
+            Cache.Entry<Object, Object> entry = 
internalCache(0).entrySet().iterator().next();
+
+            // Check thar internal entry wasn't changed.
+            assertEquals(i, ((TestKey)entry.getKey()).field());
+            assertEquals(i, ((TestValue)entry.getValue()).val());
+
+            final TestValue newTestVal = new TestValue(-i);
+
+            interceptor.delegate(new CacheInterceptorAdapter<TestKey, 
TestValue>() {
+                @Override public TestValue onBeforePut(Cache.Entry<TestKey, 
TestValue> entry, TestValue newVal) {
+                    assertNotSame(key, entry.getKey());
+                    assertNotSame(val, entry.getValue());
+
+                    assertEquals(newTestVal, newVal);
+
+                    // Try change key and value.
+                    entry.getKey().field(WRONG_VALUE);
+                    entry.getValue().val(WRONG_VALUE);
+
+                    return newVal;
+                }
+
+                @Override public void onAfterPut(Cache.Entry<TestKey, 
TestValue> entry) {
+                    assertNotSame(key, entry.getKey());
+                    assertNotSame(newTestVal, entry.getValue());
+
+                    assertSame(entry.getValue(), entry.getValue());
+                    assertSame(entry.getKey(), entry.getKey());
+
+                    // Try change key and value.
+                    entry.getKey().field(WRONG_VALUE);
+                    entry.getValue().val(WRONG_VALUE);
+                }
+            });
+
+            cache.put(key, newTestVal);
+
+            entry = internalCache(0).entrySet().iterator().next();
+
+            // Check thar internal entry wasn't changed.
+            assertEquals(i, ((TestKey)entry.getKey()).field());
+            assertEquals(-i, ((TestValue)entry.getValue()).val());
+
+            interceptor.delegate(new CacheInterceptorAdapter<TestKey, 
TestValue>() {
+                @Override public IgniteBiTuple 
onBeforeRemove(Cache.Entry<TestKey, TestValue> entry) {
+                    assertNotSame(key, entry.getKey());
+                    assertNotSame(newTestVal, entry.getValue());
+
+                    return super.onBeforeRemove(entry);
+                }
+
+                @Override public void onAfterRemove(Cache.Entry<TestKey, 
TestValue> entry) {
+                    assertNotSame(key, entry.getKey());
+                    assertNotSame(newTestVal, entry.getValue());
+                }
+            });
+
+            cache.remove(key);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testEntryProcessor() throws Exception {
+        IgniteCache<TestKey, TestValue> cache = grid(0).jcache(null);
+
+        Set<TestKey> keys = new LinkedHashSet<>();
+
+        for (int i = 0; i < ITER_CNT; i++) {
+            TestKey key = new TestKey(i, i);
+            keys.add(key);
+
+            cache.put(key, new TestValue(i));
+        }
+
+        for (int i = 0; i < ITER_CNT; i++) {
+            cache.invoke(new TestKey(i, i), new EntryProcessor<TestKey, 
TestValue, Object>() {
+                @Override public Object process(MutableEntry<TestKey, 
TestValue> entry, Object... arguments)
+                    throws EntryProcessorException {
+                    // Try change entry.
+                    entry.getKey().field(WRONG_VALUE);
+                    entry.getValue().val(WRONG_VALUE);
+   
+                    return -1;
+                }
+            });
+
+            // Check that internal entry isn't changed.
+            Cache.Entry<Object, Object> e = internalCache(0).entry(new 
TestKey(i, i));
+
+            assertEquals(i, ((TestKey)e.getKey()).field());
+            assertEquals(i, ((TestValue)e.getValue()).val());
+        }
+        
+        cache.invokeAll(keys, new EntryProcessor<TestKey, TestValue, Object>() 
{
+            @Override public Object process(MutableEntry<TestKey, TestValue> 
entry, Object... arguments) 
+                throws EntryProcessorException {
+                // Try change entry.
+                entry.getKey().field(WRONG_VALUE);
+                entry.getValue().val(WRONG_VALUE);
+                
+                return -1;
+            }
+        });
+
+        // Check that entries weren't changed.
+        for (Cache.Entry<Object, Object> e : internalCache(0).entrySet()) {
+            assertNotEquals(WRONG_VALUE, ((TestKey)e.getKey()).field());
+            assertNotEquals(WRONG_VALUE, ((TestValue)e.getValue()).val());
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testInvokeAndInterceptor() throws Exception {
+        IgniteCache<TestKey, TestValue> cache = grid(0).jcache(null);
+
+        for (int i = 0; i < ITER_CNT; i++)
+            cache.put(new TestKey(i, i), new TestValue(i));
+
+        interceptor.delegate(new CacheInterceptorAdapter<TestKey, TestValue>(){
+            @Override public TestValue onBeforePut(Cache.Entry<TestKey, 
TestValue> entry, TestValue newVal) {
+                // Check that we have correct value and key.
+                assertEquals(entry.getKey().key(), entry.getKey().field());
+                assertEquals(entry.getKey().key(), entry.getValue().val());
+
+                // Try changed entry.
+                entry.getKey().field(WRONG_VALUE);
+                entry.getValue().val(WRONG_VALUE);
+
+                return super.onBeforePut(entry, newVal);
+            }
+
+            @Override public void onAfterPut(Cache.Entry<TestKey, TestValue> 
entry) {
+                assertEquals(entry.getKey().key(), entry.getKey().field());
+                assertEquals(entry.getKey().key(), entry.getValue().val());
+
+                entry.getValue().val(WRONG_VALUE);
+                entry.getKey().field(WRONG_VALUE);
+
+                super.onAfterPut(entry);
+            }
+        });
+
+        for (int i = 0; i < ITER_CNT; i++) 
+            cache.invoke(new TestKey(i, i), new EntryProcessor<TestKey, 
TestValue, Object>() {
+                @Override public Object process(MutableEntry<TestKey, 
TestValue> entry, Object... arguments) 
+                    throws EntryProcessorException {
+                    // Check that we have correct value and key.
+                    assertEquals(entry.getKey().key(), entry.getKey().field());
+                    assertEquals(entry.getKey().key(), entry.getValue().val());
+
+                    // Try changed entry.
+                    entry.getKey().field(WRONG_VALUE);
+                    entry.getValue().val(WRONG_VALUE);
+                    
+                    return -1;
+                }
+            });
+
+        // Check that entries weren't changed.
+        for (Cache.Entry<Object, Object> e : internalCache(0).entrySet()) {
+            assertNotEquals(WRONG_VALUE, ((TestKey)e.getKey()).field());
+            assertNotEquals(WRONG_VALUE, ((TestValue)e.getValue()).val());
+        }
+    }
+
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testInvokeAllAndInterceptor() throws Exception {
+        IgniteCache<TestKey, TestValue> cache = grid(0).jcache(null);
+
+        Set<TestKey> keys = new LinkedHashSet<>();
+        
+        for (int i = 0; i < ITER_CNT; i++) {
+            TestKey key = new TestKey(i, i);
+
+            keys.add(key);
+
+            cache.put(key, new TestValue(i));
+        }
+
+        interceptor.delegate(new CacheInterceptorAdapter<TestKey, TestValue>(){
+            @Override public TestValue onBeforePut(Cache.Entry<TestKey, 
TestValue> entry, TestValue newVal) {
+                // Check that we have correct value and key.
+                assertEquals(entry.getKey().key(), entry.getKey().field());
+                assertEquals(entry.getKey().key(), entry.getValue().val());
+
+                // Try changed entry.
+                entry.getKey().field(WRONG_VALUE);
+                entry.getValue().val(WRONG_VALUE);
+
+                return super.onBeforePut(entry, newVal);
+            }
+
+            @Override public void onAfterPut(Cache.Entry<TestKey, TestValue> 
entry) {
+                // Check that we have correct value and key.
+                assertEquals(entry.getKey().key(), entry.getKey().field());
+                assertEquals(entry.getKey().key(), entry.getValue().val());
+
+                // Try changed entry.
+                entry.getValue().val(WRONG_VALUE);
+                entry.getKey().field(WRONG_VALUE);
+
+                super.onAfterPut(entry);
+            }
+        });
+
+        cache.invokeAll(keys, new EntryProcessor<TestKey, TestValue, Object>() 
{
+            @Override public Object process(MutableEntry<TestKey, TestValue> 
entry, Object... arguments)
+                throws EntryProcessorException {
+                // Check that we have correct value and key.
+                assertEquals(entry.getKey().key(), entry.getKey().field());
+                assertEquals(entry.getKey().key(), entry.getValue().val());
+
+                // Try changed entry.
+                entry.getKey().field(WRONG_VALUE);
+                entry.getValue().val(WRONG_VALUE);
+
+                return -1;
+            }
+        });
+
+        // Check that entries weren't changed.
+        for (Cache.Entry<Object, Object> e : internalCache(0).entrySet()) {
+            assertNotEquals(WRONG_VALUE, ((TestKey)e.getKey()).field());
+            assertNotEquals(WRONG_VALUE, ((TestValue)e.getValue()).val());
+        }
+    }
+
+    /**
+     *
+     */
+    public static class TestKey implements Externalizable {
+        /** */
+        private int key;
+
+        /** */
+        private int field;
+
+        /**
+         * Constructor.
+         *
+         * @param key Key.
+         */
+        public TestKey(int key, int field) {
+            this.key = key;
+            this.field = field;
+        }
+
+        /**
+         * Default constructor.
+         */
+        public TestKey() {
+            // No-op.
+        }
+
+        /**
+         * @return key Key.
+         */
+        public int key(){
+            return key;
+        }
+
+        /**
+         * @return Test field.
+         */
+        public int field() {
+            return field;
+        }
+
+        /**
+         * *
+         * @param field Test field.
+         */
+        public void field(int field) {
+            this.field = field;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o) return true;
+
+            if (o == null || getClass() != o.getClass()) return false;
+
+            TestKey testKey = (TestKey) o;
+
+            return key == testKey.key;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return key;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws 
IOException {
+            out.writeInt(key);
+            out.writeInt(field);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
+            key = in.readInt();
+            field = in.readInt();
+        }
+    }
+
+
+    /**
+     *
+     */
+    public static class TestValue implements Externalizable {
+        /** */
+        private int val;
+
+        /**
+         * Constructor.
+         *
+         * @param val Value.
+         */
+        public TestValue(int val) {
+            this.val = val;
+        }
+
+        /**
+         * Default constructor.
+         */
+        public TestValue() {
+            // No-op.
+        }
+
+        /**
+         * @return Value.
+         */
+        public int val() {
+            return val;
+        }
+
+        /**
+         * @param val Value.
+         */
+        public void val(int val) {
+            this.val = val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o) return true;
+
+            if (o == null || getClass() != o.getClass()) return false;
+
+            TestValue testKey = (TestValue)o;
+
+            return val == testKey.val;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws 
IOException {
+            out.writeInt(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
+            val = in.readInt();
+        }
+    }
+
+    /**
+     *
+     */
+    private class Interceptor implements CacheInterceptor<TestKey, TestValue> {
+        /** */
+        CacheInterceptor<TestKey, TestValue> delegate = new 
CacheInterceptorAdapter<>();
+
+        /** {@inheritDoc} */
+        @Override public TestValue onGet(TestKey key, @Nullable TestValue val) 
{
+            return delegate.onGet(key, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public TestValue onBeforePut(Cache.Entry<TestKey, TestValue> 
entry, TestValue newVal) {
+            return delegate.onBeforePut(entry, newVal);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onAfterPut(Cache.Entry<TestKey, TestValue> 
entry) {
+            delegate.onAfterPut(entry);
+        }
+
+        /** {@inheritDoc} */
+        @Override public IgniteBiTuple<Boolean, TestValue> 
onBeforeRemove(Cache.Entry<TestKey, TestValue> entry) {
+            return delegate.onBeforeRemove(entry);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onAfterRemove(Cache.Entry<TestKey, TestValue> 
entry) {
+            delegate.onAfterRemove(entry);
+        }
+
+        /**
+         * @param delegate Cache interceptor delegate.
+         */
+        public void delegate(CacheInterceptor<TestKey, TestValue> delegate) {
+            this.delegate = delegate;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAtomicSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAtomicSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAtomicSelfTest.java
new file mode 100644
index 0000000..07beef5
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagAtomicSelfTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.cache.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+
+/**
+ * Tests {@link org.apache.ignite.cache.CacheInterceptor}.
+ */
+public class GridCacheOnFlagAtomicSelfTest extends
+    GridCacheOnFlagAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheMode cacheMode() {
+        return PARTITIONED;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return ATOMIC;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagLocalSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagLocalSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagLocalSelfTest.java
new file mode 100644
index 0000000..9bc8032
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagLocalSelfTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.cache.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+
+/**
+ * Tests {@link org.apache.ignite.cache.CacheInterceptor}.
+ */
+public class GridCacheOnFlagLocalSelfTest extends
+    GridCacheOnFlagAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheMode cacheMode() {
+        return LOCAL;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return ATOMIC;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagReplicatedSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagReplicatedSelfTest.java
new file mode 100644
index 0000000..66c33e8
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagReplicatedSelfTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.cache.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+
+/**
+ * Tests {@link org.apache.ignite.cache.CacheInterceptor}.
+ */
+public class GridCacheOnFlagReplicatedSelfTest extends
+    GridCacheOnFlagAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheMode cacheMode() {
+        return REPLICATED;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return ATOMIC;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/00e03889/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagTxPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagTxPartitionedSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagTxPartitionedSelfTest.java
new file mode 100644
index 0000000..688c4f8
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnFlagTxPartitionedSelfTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.cache.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+
+/**
+ * Tests {@link org.apache.ignite.cache.CacheInterceptor}.
+ */
+public class GridCacheOnFlagTxPartitionedSelfTest extends
+    GridCacheOnFlagAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheMode cacheMode() {
+        return PARTITIONED;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return TRANSACTIONAL;
+    }
+}

Reply via email to