Index: core/src/main/java/org/infinispan/marshall/MarshalledValue.java =================================================================== --- core/src/main/java/org/infinispan/marshall/MarshalledValue.java (revision 2324) +++ core/src/main/java/org/infinispan/marshall/MarshalledValue.java (revision ) @@ -180,7 +180,7 @@ if (instance != null && that.instance != null) return instance.equals(that.instance); // if conversion of one representation to the other is necessary, then see which we prefer converting. - if (equalityPreferenceForInstance) { + if (equalityPreferenceForInstance && that.equalityPreferenceForInstance) { if (instance == null) deserialize(); if (that.instance == null) that.deserialize(); return instance.equals(that.instance); @@ -216,6 +216,11 @@ return sb.toString(); } + public MarshalledValue setEqualityPreferenceForInstance(boolean equalityPreferenceForInstance) { + this.equalityPreferenceForInstance = equalityPreferenceForInstance; + return this; + } + /** * Tests whether the type should be excluded from MarshalledValue wrapping. * Index: core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java =================================================================== --- core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java (revision 1467) +++ core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java (revision ) @@ -478,6 +478,17 @@ assert !cache1.containsKey(pojo); } + public void testModificationsOnSameCustomKey() { + Cache cache1 = cache(0, "replSync"); + Cache cache2 = cache(1, "replSync"); + + Pojo key = new Pojo(); + cache1.put(key, "1"); + cache2.put(key, "2"); + + assertSerializationCounts(3, 0); + } + @Listener public static class MockListener { Object newValue; Index: core/src/main/java/org/infinispan/interceptors/MarshalledValueInterceptor.java =================================================================== --- core/src/main/java/org/infinispan/interceptors/MarshalledValueInterceptor.java (revision 2165) +++ core/src/main/java/org/infinispan/interceptors/MarshalledValueInterceptor.java (revision ) @@ -26,6 +26,7 @@ import org.infinispan.commands.read.GetKeyValueCommand; import org.infinispan.commands.read.KeySetCommand; import org.infinispan.commands.read.ValuesCommand; +import org.infinispan.commands.write.InvalidateCommand; import org.infinispan.commands.write.PutKeyValueCommand; import org.infinispan.commands.write.PutMapCommand; import org.infinispan.commands.write.RemoveCommand; @@ -113,6 +114,12 @@ value = createMarshalledValue(command.getValue(), ctx); command.setValue(value); } + + // If origin is remote, set equality preference for raw so that deserialization is avoided + // Don't do this for local invocations so that unnecessary serialization is avoided. + if (!ctx.isOriginLocal() && command.getKey() instanceof MarshalledValue) + ((MarshalledValue) command.getKey()).setEqualityPreferenceForInstance(false); + Object retVal = invokeNextInterceptor(ctx, command); compact(key); compact(value); @@ -224,6 +231,20 @@ return processRetVal(retVal); } + @Override + public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand command) throws Throwable { + // If origin is remote, set equality preference for raw so that deserialization is avoided + // Don't do this for local invocations so that unnecessary serialization is avoided. + if (!ctx.isOriginLocal()) { + for (Object key : command.getKeys()) { + if (key instanceof MarshalledValue) + ((MarshalledValue) key).setEqualityPreferenceForInstance(false); + } + } + + return invokeNextInterceptor(ctx, command); + } + private Object compactAndProcessRetVal(Set marshalledValues, Object retVal) throws IOException, ClassNotFoundException { if (trace) log.trace("Compacting MarshalledValues created"); Index: core/src/test/java/org/infinispan/marshall/InvalidatedMarshalledValueTest.java =================================================================== --- core/src/test/java/org/infinispan/marshall/InvalidatedMarshalledValueTest.java (revision ) +++ core/src/test/java/org/infinispan/marshall/InvalidatedMarshalledValueTest.java (revision ) @@ -0,0 +1,56 @@ +package org.infinispan.marshall; + +import org.infinispan.Cache; +import org.infinispan.config.Configuration; +import org.infinispan.interceptors.InterceptorChain; +import org.infinispan.interceptors.MarshalledValueInterceptor; +import org.infinispan.test.MultipleCacheManagersTest; +import org.infinispan.test.TestingUtil; +import org.testng.annotations.Test; +import org.infinispan.marshall.MarshalledValueTest.Pojo; + +/** + * // TODO: Document this + * + * @author Galder Zamarre–o + * @since // TODO + */ +@Test(groups = "functional", testName = "marshall.InvalidatedMarshalledValueTest") +public class InvalidatedMarshalledValueTest extends MultipleCacheManagersTest { + + protected void createCacheManagers() throws Throwable { + Cache cache1, cache2; + Configuration invlSync = getDefaultClusteredConfig(Configuration.CacheMode.INVALIDATION_SYNC); + invlSync.setUseLazyDeserialization(true); + + createClusteredCaches(2, "invlSync", invlSync); + + cache1 = cache(0, "invlSync"); + cache2 = cache(1, "invlSync"); + + assertMarshalledValueInterceptorPresent(cache1); + assertMarshalledValueInterceptorPresent(cache2); + } + + private void assertMarshalledValueInterceptorPresent(Cache c) { + InterceptorChain ic1 = TestingUtil.extractComponent(c, InterceptorChain.class); + assert ic1.containsInterceptorType(MarshalledValueInterceptor.class); + } + + public void testModificationsOnSameCustomKey() { + Cache cache1 = cache(0, "invlSync"); + Cache cache2 = cache(1, "invlSync"); + + Pojo key = new Pojo(); + cache2.put(key, "1"); + cache1.put(key, "1"); + + assertSerializationCounts(3, 0); + } + + private void assertSerializationCounts(int serializationCount, int deserializationCount) { + assert Pojo.serializationCount == serializationCount : "Serialization count: expected " + serializationCount + " but was " + Pojo.serializationCount; + assert Pojo.deserializationCount == deserializationCount : "Deserialization count: expected " + deserializationCount + " but was " + Pojo.deserializationCount; + } + +}