You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/06/19 12:35:18 UTC

[32/50] incubator-ignite git commit: ignite-950: managed to run SQL queries with indexed fields in footer

ignite-950: managed to run SQL queries with indexed fields in footer


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

Branch: refs/heads/ignite-950
Commit: 25d0da2d0ed44cbb46904863ab43a22445e0f46d
Parents: 74017fa
Author: Denis Magda <dm...@gridgain.com>
Authored: Thu Jun 18 14:15:43 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Thu Jun 18 14:15:43 2015 +0300

----------------------------------------------------------------------
 .../processors/cache/CacheObjectContext.java    | 93 ++++++++++++++++++--
 .../cache/CacheOptimizedObjectImpl.java         | 80 +++++++++++------
 .../processors/cache/GridCacheAdapter.java      | 10 +--
 .../processors/cache/GridCacheContext.java      | 24 +++--
 .../cache/KeyCacheOptimizedObjectImpl.java      | 12 ++-
 .../distributed/near/GridNearGetFuture.java     |  4 +-
 .../query/GridCacheQueryFutureAdapter.java      |  2 +-
 .../cache/query/GridCacheQueryManager.java      | 12 +--
 .../store/GridCacheStoreManagerAdapter.java     | 31 ++++---
 .../cacheobject/IgniteCacheObjectProcessor.java | 11 ++-
 .../IgniteCacheObjectProcessorImpl.java         | 34 ++++---
 .../query/GridQueryCacheObjectsIterator.java    |  2 +-
 .../processors/query/GridQueryProcessor.java    |  9 +-
 .../internal/util/io/GridUnsafeDataInput.java   |  5 +-
 .../optimized/OptimizedMarshallerUtils.java     | 23 +++++
 .../optimized/ext/OptimizedMarshallerExt.java   |  9 ++
 .../ext/OptimizedObjectInputStreamExt.java      |  9 +-
 ...acheOptimizedMarshallerExtQuerySelfTest.java | 15 ++++
 18 files changed, 278 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
index cf35177..b0e3a0d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
@@ -20,6 +20,9 @@ package org.apache.ignite.internal.processors.cache;
 import org.apache.ignite.cache.affinity.*;
 import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.processors.cacheobject.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.marshaller.optimized.*;
 
 import java.util.*;
 
@@ -120,24 +123,102 @@ public class CacheObjectContext {
     }
 
     /**
-     * Unwraps object.
+     * Unwraps object if needed.
      *
      * @param o Object to unwrap.
-     * @param keepPortable Keep portable flag.
+     * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases.
      * @return Unwrapped object.
      */
-    public Object unwrapPortableIfNeeded(Object o, boolean keepPortable) {
+    public Object unwrapIfNeeded(Object o, boolean keepPortable) {
+        if (processor().isFieldsIndexingEnabled() && OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(o))
+            return unwrapObject(o);
+
         return o;
     }
 
     /**
-     * Unwraps collection.
+     * Unwraps collection if needed.
      *
      * @param col Collection to unwrap.
-     * @param keepPortable Keep portable flag.
+     * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases.
      * @return Unwrapped collection.
      */
-    public Collection<Object> unwrapPortablesIfNeeded(Collection<Object> col, boolean keepPortable) {
+    public Collection<Object> unwrapIfNeeded(Collection<Object> col, boolean keepPortable) {
+        if (processor().isFieldsIndexingEnabled())
+            return (Collection<Object>)unwrapObject(col);
+
         return col;
     }
+
+    /**
+     * Unwraps object if needed.
+     *
+     * @param obj Object to unwrap.
+     * @return Unwrapped object.
+     */
+    private Object unwrapObject(Object obj) {
+        if (obj instanceof CacheOptimizedObjectImpl)
+            return ((CacheOptimizedObjectImpl)obj).deserialize(this);
+        else if (obj instanceof Map.Entry) {
+            Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>)obj;
+
+            Object key = entry.getKey();
+
+            boolean unwrapped = false;
+
+            if (key instanceof CacheOptimizedObjectImpl) {
+                key = ((CacheOptimizedObjectImpl)key).deserialize(this);
+
+                unwrapped = true;
+            }
+
+            Object val = entry.getValue();
+
+            if (val instanceof CacheOptimizedObjectImpl) {
+                val = ((CacheOptimizedObjectImpl)val).deserialize(this);
+
+                unwrapped = true;
+            }
+
+            return unwrapped ? F.t(key, val) : obj;
+        }
+        else if (obj instanceof Collection) {
+            Collection<Object> col = (Collection<Object>)obj;
+
+            if (col instanceof ArrayList) {
+                ArrayList<Object> list = (ArrayList<Object>)col;
+
+                int size = list.size();
+
+                for (int i = 0; i < size; i++) {
+                    Object old = list.get(i);
+
+                    Object unwrapped = unwrapObject(old);
+
+                    if (old != unwrapped)
+                        list.set(i, unwrapped);
+                }
+
+                return list;
+            }
+            else {
+                Collection<Object> col0 = new ArrayList<>(col.size());
+
+                for (Object obj0 : col)
+                    col0.add(unwrapObject(obj0));
+
+                return col0;
+            }
+        }
+        else if (obj instanceof Map) {
+            Map<Object, Object> map = (Map<Object, Object>)obj;
+
+            Map<Object, Object> map0 = U.newHashMap(map.size());
+
+            for (Map.Entry<Object, Object> e : map.entrySet())
+                map0.put(unwrapObject(e.getKey()), unwrapObject(e.getValue()));
+        }
+
+        return obj;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java
index 078b4de..fe5a644 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java
@@ -18,10 +18,12 @@
 package org.apache.ignite.internal.processors.cache;
 
 import org.apache.ignite.*;
+import org.apache.ignite.internal.util.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 import org.apache.ignite.marshaller.optimized.ext.*;
 import org.apache.ignite.plugin.extensions.communication.*;
 import org.jetbrains.annotations.*;
+import sun.misc.*;
 
 import java.io.*;
 import java.nio.*;
@@ -35,6 +37,12 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter {
     private static final long serialVersionUID = 0L;
 
     /** */
+    private static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+    /** */
+    private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
+
+    /** */
     protected int start;
 
     /** */
@@ -92,33 +100,7 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter {
 
     /** {@inheritDoc} */
     @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
-        //return (T)this;
-        cpy = cpy && needCopy(ctx);
-
-        try {
-            if (cpy) {
-                toMarshaledFormIfNeeded(ctx);
-
-                return (T)ctx.processor().unmarshal(ctx, valBytes,
-                    val == null ? ctx.kernalContext().config().getClassLoader() : val.getClass().getClassLoader());
-            }
-
-            if (val != null)
-                return (T)val;
-
-            assert valBytes != null;
-
-            Object val = ctx.processor().unmarshal(ctx, valBytes, start, len,
-                ctx.kernalContext().config().getClassLoader());
-
-            if (ctx.storeValue())
-                this.val = val;
-
-            return (T)val;
-        }
-        catch (IgniteCheckedException e) {
-            throw new IgniteException("Failed to unmarshall object.", e);
-        }
+        return (T)this;
     }
 
     /** {@inheritDoc} */
@@ -170,6 +152,22 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter {
     }
 
     /**
+     * Returns object's type ID.
+     *
+     * @return Type ID.
+     */
+    public int typeId() {
+        assert valBytes != null;
+
+        int typeId = UNSAFE.getInt(valBytes, BYTE_ARR_OFF + start + 1);
+
+        if (typeId == 0)
+            throw new IgniteException("Object's type ID wasn't written to cache.");
+
+        return typeId;
+    }
+
+    /**
      * Checks whether a wrapped object has field with name {@code fieldName}.
      *
      * @param fieldName Field name.
@@ -194,7 +192,33 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter {
     public Object field(String fieldName, OptimizedMarshallerExt marsh) throws IgniteCheckedException {
         assert valBytes != null;
 
-        return marsh.readField(fieldName, valBytes, start, len, val != null ?  val.getClass().getClassLoader() : null);
+        return marsh.readField(fieldName, valBytes, start, len, val != null ? val.getClass().getClassLoader() : null);
+    }
+
+    /**
+     * Deserializes wrapped object.
+     *
+     * @param ctx Cache context.
+     * @return Deserialized object.
+     */
+    public Object deserialize(CacheObjectContext ctx) {
+        if (val != null)
+            return val;
+
+        try {
+            assert valBytes != null;
+
+            Object val = ctx.processor().unmarshal(ctx, valBytes, start, len,
+                ctx.kernalContext().config().getClassLoader());
+
+            if (ctx.storeValue())
+                this.val = val;
+
+            return val;
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to unmarshall object.", e);
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 2ca7687..2709f60 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -724,7 +724,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
             Object val = CU.value(cacheVal, ctx, true);
 
-            val = ctx.unwrapPortableIfNeeded(val, ctx.keepPortable());
+            val = ctx.unwrapIfNeeded(val, ctx.keepPortable());
 
             return (V)val;
         }
@@ -3775,7 +3775,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         Object val0 = val != null ? val.value(ctx.cacheObjectContext(), true) : null;
 
-        return (V)ctx.unwrapPortableIfNeeded(val0, !deserializePortable);
+        return (V)ctx.unwrapIfNeeded(val0, !deserializePortable);
     }
 
     /** {@inheritDoc} */
@@ -4588,10 +4588,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             Object key0 = key.value(ctx.cacheObjectContext(), true);
             Object val0 = val.value(ctx.cacheObjectContext(), true);
 
-            if (deserializePortable) {
-                key0 = ctx.unwrapPortableIfNeeded(key0, true);
-                val0 = ctx.unwrapPortableIfNeeded(val0, true);
-            }
+            key0 = ctx.unwrapIfNeeded(key0, !deserializePortable);
+            val0 = ctx.unwrapIfNeeded(val0, !deserializePortable);
 
             return new CacheEntryImpl<>((K)key0, (V)val0);
         }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index 8a4e3b9..d7bb295 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -1678,26 +1678,26 @@ public class GridCacheContext<K, V> implements Externalizable {
     }
 
     /**
-     * Unwraps collection.
+     * Unwraps collection if needed.
      *
      * @param col Collection to unwrap.
-     * @param keepPortable Keep portable flag.
+     * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases.
      * @return Unwrapped collection.
      */
-    public Collection<Object> unwrapPortablesIfNeeded(Collection<Object> col, boolean keepPortable) {
-        return cacheObjCtx.unwrapPortablesIfNeeded(col, keepPortable);
+    public Collection<Object> unwrapIfNeeded(Collection<Object> col, boolean keepPortable) {
+        return cacheObjCtx.unwrapIfNeeded(col, keepPortable);
     }
 
     /**
-     * Unwraps object for portables.
+     * Unwraps object if needed.
      *
      * @param o Object to unwrap.
-     * @param keepPortable Keep portable flag.
+     * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases.
      * @return Unwrapped object.
      */
     @SuppressWarnings("IfMayBeConditional")
-    public Object unwrapPortableIfNeeded(Object o, boolean keepPortable) {
-        return cacheObjCtx.unwrapPortableIfNeeded(o, keepPortable);
+    public Object unwrapIfNeeded(Object o, boolean keepPortable) {
+        return cacheObjCtx.unwrapIfNeeded(o, keepPortable);
     }
 
     /**
@@ -1795,12 +1795,10 @@ public class GridCacheContext<K, V> implements Externalizable {
             Object key0 = key.value(cacheObjCtx, false);
             Object val0 = skipVals ? true : val.value(cacheObjCtx, cpy);
 
-            if (deserializePortable) {
-                key0 = unwrapPortableIfNeeded(key0, false);
+            key0 = unwrapIfNeeded(key0, !deserializePortable);
 
-                if (!skipVals)
-                    val0 = unwrapPortableIfNeeded(val0, false);
-            }
+            if (!skipVals)
+                val0 = unwrapIfNeeded(val0, !deserializePortable);
 
             assert key0 != null : key;
             assert val0 != null : val;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java
index 8322e7a..56e6fe2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java
@@ -57,10 +57,7 @@ public class KeyCacheOptimizedObjectImpl extends CacheOptimizedObjectImpl implem
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
-        //return (T)this;
-        assert val != null;
-
-        return (T)val;
+        return (T)this;
     }
 
     /** {@inheritDoc} */
@@ -82,6 +79,13 @@ public class KeyCacheOptimizedObjectImpl extends CacheOptimizedObjectImpl implem
     }
 
     /** {@inheritDoc} */
+    @Override public Object deserialize(CacheObjectContext ctx) {
+        assert val != null;
+
+        return val;
+    }
+
+    /** {@inheritDoc} */
     @Override public int hashCode() {
         assert val != null;
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index 74438bb..06aae28 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -499,8 +499,8 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                     K key0 = key.value(cctx.cacheObjectContext(), true);
                     V val0 = v.value(cctx.cacheObjectContext(), true);
 
-                    val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable);
-                    key0 = (K)cctx.unwrapPortableIfNeeded(key0, !deserializePortable);
+                    val0 = (V)cctx.unwrapIfNeeded(val0, !deserializePortable);
+                    key0 = (K)cctx.unwrapIfNeeded(key0, !deserializePortable);
 
                     add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
                 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java
index a8bace0..31d008f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java
@@ -380,7 +380,7 @@ public abstract class GridCacheQueryFutureAdapter<K, V, R> extends GridFutureAda
 
                 data = dedupIfRequired((Collection<Object>)data);
 
-                data = cctx.unwrapPortablesIfNeeded((Collection<Object>)data, qry.query().keepPortable());
+                data = cctx.unwrapIfNeeded((Collection<Object>)data, qry.query().keepPortable());
 
                 synchronized (mux) {
                     enqueue(data);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
index 1317d38..073bf79 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
@@ -894,7 +894,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
 
                 private boolean checkPredicate(Map.Entry<K, V> e) {
                     if (keyValFilter != null) {
-                        Map.Entry<K, V> e0 = (Map.Entry<K, V>)cctx.unwrapPortableIfNeeded(e, qry.keepPortable());
+                        Map.Entry<K, V> e0 = (Map.Entry<K, V>)cctx.unwrapIfNeeded(e, qry.keepPortable());
 
                         return keyValFilter.apply(e0.getKey(), e0.getValue());
                     }
@@ -1030,8 +1030,8 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
                     final LazySwapEntry e = new LazySwapEntry(it.next());
 
                     if (filter != null) {
-                        K key = (K)cctx.unwrapPortableIfNeeded(e.key(), keepPortable);
-                        V val = (V)cctx.unwrapPortableIfNeeded(e.value(), keepPortable);
+                        K key = (K)cctx.unwrapIfNeeded(e.key(), keepPortable);
+                        V val = (V)cctx.unwrapIfNeeded(e.value(), keepPortable);
 
                         if (!filter.apply(key, val))
                             continue;
@@ -1440,7 +1440,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
 
                     // Unwrap entry for reducer or transformer only.
                     if (rdc != null || trans != null)
-                        entry = (Map.Entry<K, V>)cctx.unwrapPortableIfNeeded(entry, qry.keepPortable());
+                        entry = (Map.Entry<K, V>)cctx.unwrapIfNeeded(entry, qry.keepPortable());
 
                     // Reduce.
                     if (rdc != null) {
@@ -2534,8 +2534,8 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
             throws IgniteCheckedException {
             LazyOffheapEntry e = new LazyOffheapEntry(keyPtr, valPtr);
 
-            K key = (K)cctx.unwrapPortableIfNeeded(e.key(), keepPortable);
-            V val = (V)cctx.unwrapPortableIfNeeded(e.value(), keepPortable);
+            K key = (K)cctx.unwrapIfNeeded(e.key(), keepPortable);
+            V val = (V)cctx.unwrapIfNeeded(e.value(), keepPortable);
 
             if (!filter.apply(key, val))
                 return null;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
index b4a146a..32882ff 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
@@ -31,6 +31,7 @@ import org.apache.ignite.internal.util.typedef.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 import org.apache.ignite.lang.*;
 import org.apache.ignite.lifecycle.*;
+import org.apache.ignite.marshaller.optimized.*;
 import org.apache.ignite.transactions.*;
 import org.jetbrains.annotations.*;
 
@@ -244,8 +245,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
 
             Object storeKey = key.value(cctx.cacheObjectContext(), false);
 
-            if (convertPortable())
-                storeKey = cctx.unwrapPortableIfNeeded(storeKey, false);
+            if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(storeKey) || convertPortable())
+                storeKey = cctx.unwrapIfNeeded(storeKey, false);
 
             if (log.isDebugEnabled())
                 log.debug("Loading value from store for key: " + storeKey);
@@ -371,10 +372,10 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
 
             Collection<Object> keys0;
 
-            if (convertPortable()) {
+            if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(keys) || convertPortable()) {
                 keys0 = F.viewReadOnly(keys, new C1<KeyCacheObject, Object>() {
                     @Override public Object apply(KeyCacheObject key) {
-                        return cctx.unwrapPortableIfNeeded(key.value(cctx.cacheObjectContext(), false), false);
+                        return cctx.unwrapIfNeeded(key.value(cctx.cacheObjectContext(), false), false);
                     }
                 });
             }
@@ -505,9 +506,11 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
             if (key instanceof GridCacheInternal)
                 return true;
 
-            if (convertPortable()) {
-                key = cctx.unwrapPortableIfNeeded(key, false);
-                val = cctx.unwrapPortableIfNeeded(val, false);
+            if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(key) ||
+                OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(val) ||
+                convertPortable()) {
+                key = cctx.unwrapIfNeeded(key, false);
+                val = cctx.unwrapIfNeeded(val, false);
             }
 
             if (log.isDebugEnabled())
@@ -610,8 +613,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
             if (key instanceof GridCacheInternal)
                 return false;
 
-            if (convertPortable())
-                key = cctx.unwrapPortableIfNeeded(key, false);
+            if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(key) || convertPortable())
+                key = cctx.unwrapIfNeeded(key, false);
 
             if (log.isDebugEnabled())
                 log.debug("Removing value from cache store [key=" + key + ']');
@@ -659,7 +662,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
         }
 
         if (store != null) {
-            Collection<Object> keys0 = convertPortable() ? cctx.unwrapPortablesIfNeeded(keys, false) : keys;
+            Collection<Object> keys0 = convertPortable() ? cctx.unwrapIfNeeded(keys, false) : keys;
 
             if (log.isDebugEnabled())
                 log.debug("Removing values from cache store [keys=" + keys0 + ']');
@@ -1076,9 +1079,11 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
 
                         Object v = locStore ? e.getValue() : e.getValue().get1();
 
-                        if (convertPortable()) {
-                            k = cctx.unwrapPortableIfNeeded(k, false);
-                            v = cctx.unwrapPortableIfNeeded(v, false);
+                        if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(k) ||
+                            OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(v) ||
+                            convertPortable()) {
+                            k = cctx.unwrapIfNeeded(k, false);
+                            v = cctx.unwrapIfNeeded(v, false);
                         }
 
                         next = new CacheEntryImpl<>(k, v);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java
index 0a6a188..42ccbce 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java
@@ -98,6 +98,13 @@ public interface IgniteCacheObjectProcessor extends GridProcessor {
     public boolean hasField(Object obj, String fieldName);
 
     /**
+     * Checks whether this functionality is globally supported.
+     *
+     * @return {@code true} if enabled.
+     */
+    public boolean isFieldsIndexingEnabled();
+
+    /**
      * Checks whether fields indexing is supported by footer injection into a serialized form of the object.
      * Footer contains information about fields location in the serialized form, thus enabling fast queries without
      * a need to deserialize the object.
@@ -105,9 +112,9 @@ public interface IgniteCacheObjectProcessor extends GridProcessor {
      * Indexing is enabled with {@link OptimizedMarshallerExt#enableFieldsIndexing(Class)}.
      *
      * @param cls Class.
-     * @return {@code true} if the footer is supported.
+     * @return {@code true} if the footer is enabled.
      */
-    public boolean isFieldsIndexingSupported(Class<?> cls);
+    public boolean isFieldsIndexingEnabled(Class<?> cls);
 
     /**
      * Tries to enables fields indexing for the object of the given {@code cls}.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
index 6d222dc..64aa064 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
@@ -28,6 +28,7 @@ import org.apache.ignite.internal.util.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 import org.apache.ignite.lang.*;
 import org.apache.ignite.marshaller.*;
+import org.apache.ignite.marshaller.optimized.*;
 import org.apache.ignite.marshaller.optimized.ext.*;
 import org.jetbrains.annotations.*;
 
@@ -193,10 +194,10 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
     @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor")
     protected KeyCacheObject toCacheKeyObject0(Object obj, boolean userObj) {
         if (!userObj)
-            return isFieldsIndexingSupported(obj.getClass()) ? new KeyCacheOptimizedObjectImpl(obj, null) :
+            return isFieldsIndexingEnabled(obj.getClass()) ? new KeyCacheOptimizedObjectImpl(obj, null) :
                 new KeyCacheObjectImpl(obj, null);
 
-        return isFieldsIndexingSupported(obj.getClass()) ? new UserKeyCacheOptimizedObjectImpl(obj) :
+        return isFieldsIndexingEnabled(obj.getClass()) ? new UserKeyCacheOptimizedObjectImpl(obj) :
             new UserKeyCacheObjectImpl(obj);
     }
 
@@ -268,10 +269,10 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
         }
 
         if (!userObj)
-            return isFieldsIndexingSupported(obj.getClass()) ? new CacheOptimizedObjectImpl(obj) :
+            return isFieldsIndexingEnabled(obj.getClass()) ? new CacheOptimizedObjectImpl(obj) :
                 new CacheObjectImpl(obj, null);
 
-        return isFieldsIndexingSupported(obj.getClass()) ? new UserCacheOptimizedObjectImpl(obj, null) :
+        return isFieldsIndexingEnabled(obj.getClass()) ? new UserCacheOptimizedObjectImpl(obj, null) :
             new UserCacheObjectImpl(obj, null);
     }
 
@@ -305,9 +306,16 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
 
     /** {@inheritDoc} */
     @Override public int typeId(String typeName) {
-        return 0;
+        return optMarshExt != null ? OptimizedMarshallerUtils.resolveTypeId(typeName, optMarshExt.idMapper()) : 0;
     }
 
+    /** {@inheritDoc} */
+    @Override public int typeId(Object obj) {
+        if (obj instanceof CacheOptimizedObjectImpl)
+            return ((CacheOptimizedObjectImpl)obj).typeId();
+
+        return 0;
+    }
 
     /** {@inheritDoc} */
     @Override public Object unwrapTemporary(GridCacheContext ctx, Object obj) throws IgniteException {
@@ -325,11 +333,6 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
     }
 
     /** {@inheritDoc} */
-    @Override public int typeId(Object obj) {
-        return 0;
-    }
-
-    /** {@inheritDoc} */
     @Override public Object field(Object obj, String fieldName) {
         if (obj instanceof CacheOptimizedObjectImpl) {
             assert optMarshExt != null;
@@ -362,7 +365,12 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
     }
 
     /** {@inheritDoc} */
-    @Override public boolean isFieldsIndexingSupported(Class<?> cls) {
+    @Override public boolean isFieldsIndexingEnabled() {
+        return optMarshExt != null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isFieldsIndexingEnabled(Class<?> cls) {
         return optMarshExt != null && optMarshExt.fieldsIndexingEnabled(cls);
     }
 
@@ -468,7 +476,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
 
     /**
      * Wraps value provided by user, must be serialized before stored in cache.
-     * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingSupported(Class)}.
+     * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingEnabled(Class)}.
      */
     private static class UserCacheOptimizedObjectImpl extends CacheOptimizedObjectImpl {
         /** */
@@ -519,7 +527,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
 
     /**
      * Wraps key provided by user, must be serialized before stored in cache.
-     * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingSupported(Class)}.
+     * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingEnabled(Class)}.
      */
     private static class UserKeyCacheOptimizedObjectImpl extends KeyCacheOptimizedObjectImpl {
         /** */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java
index 3dc7ddc..ee26609 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java
@@ -60,7 +60,7 @@ public class GridQueryCacheObjectsIterator implements Iterator<List<?>>, AutoClo
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public List<?> next() {
-        return (List<?>)cctx.unwrapPortablesIfNeeded((Collection<Object>)iter.next(), keepPortable);
+        return (List<?>)cctx.unwrapIfNeeded((Collection<Object>)iter.next(), keepPortable);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index fe7c952..3e7948e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -143,7 +143,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                     else if (ctx.cacheObjects().enableFieldsIndexing(valCls)) {
                         processIndexedFieldsMeta(meta, desc);
 
-                        typeId = new TypeId(ccfg.getName(), valCls);
+                        typeId = new TypeId(ccfg.getName(), ctx.cacheObjects().typeId(valCls.getName()));
                     }
                     else {
                         processClassMeta(meta, desc);
@@ -454,8 +454,9 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             TypeId id;
 
             boolean portableVal = ctx.cacheObjects().isPortableObject(val);
+            boolean indexedFieldsVal = val instanceof CacheOptimizedObjectImpl;
 
-            if (portableVal) {
+            if (portableVal || indexedFieldsVal) {
                 int typeId = ctx.cacheObjects().typeId(val);
 
                 id = new TypeId(space, typeId);
@@ -471,12 +472,12 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             if (desc == null || !desc.registered())
                 return;
 
-            if (!portableVal && !desc.valueClass().isAssignableFrom(valCls))
+            if (!portableVal && !indexedFieldsVal && !desc.valueClass().isAssignableFrom(valCls))
                 throw new IgniteCheckedException("Failed to update index due to class name conflict" +
                     "(multiple classes with same simple name are stored in the same cache) " +
                     "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']');
 
-            if (!ctx.cacheObjects().isPortableObject(key)) {
+            if (!(key instanceof CacheOptimizedObjectImpl) && !ctx.cacheObjects().isPortableObject(key)) {
                 Class<?> keyCls = key.value(coctx, false).getClass();
 
                 if (!desc.keyClass().isAssignableFrom(keyCls))

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
index 6be90c5..d76aac2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
@@ -109,12 +109,10 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput {
     /** {@inheritDoc} */
     @Override public void bytes(byte[] bytes, int off, int len) {
         buf = bytes;
-
-        max = len;
+        max = len + off;
         this.off = off;
     }
 
-
     /** {@inheritDoc} */
     @Override public void inputStream(InputStream in) throws IOException {
         this.in = in;
@@ -122,7 +120,6 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput {
         buf = inBuf;
     }
 
-
     /**
      * Reads from stream to buffer. If stream is {@code null}, this method is no-op.
      *

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
index 61cbcee..2f42e8d 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.marshaller.optimized;
 
 import org.apache.ignite.*;
+import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.util.*;
 import org.apache.ignite.internal.util.typedef.*;
 import org.apache.ignite.marshaller.*;
@@ -237,6 +238,28 @@ public class OptimizedMarshallerUtils {
     }
 
     /**
+     * Checks whether the given object is a wrapper, that contains serialized form of an object with indexed fields, or
+     * {@link Collection} or {@link Map}.
+     *
+     * @param obj Object.
+     * @return {@code true} if all the conditions are met..
+     */
+    public static boolean isObjectWithIndexedFieldsOrCollection(Object obj) {
+        if (obj == null)
+            return false;
+
+        if (obj instanceof CacheOptimizedObjectImpl ||
+            obj instanceof Map.Entry ||
+            obj instanceof Collection ||
+            obj instanceof Map ||
+            obj.getClass() == Object[].class)
+            return true;
+
+        return false;
+    }
+
+
+    /**
      * Gets descriptor for provided ID.
      *
      * @param clsMap Class descriptors by class map.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
index 8e2653b..1a451e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
@@ -72,6 +72,15 @@ public class OptimizedMarshallerExt extends OptimizedMarshaller {
     }
 
     /**
+     * Returns currently set ID mapper.
+     *
+     * @return ID mapper.
+     */
+    public OptimizedMarshallerIdMapper idMapper() {
+        return mapper;
+    }
+
+    /**
      * Enables fields indexing for the object of the given {@code cls}.
      *
      * If enabled then a footer will be added during marshalling of an object of the given {@code cls} to the end of

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
index 977a988..7ab56a2 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
@@ -83,7 +83,7 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream {
             return false;
         }
 
-        FieldRange range = fieldRange(fieldName);
+        FieldRange range = fieldRange(fieldName, pos);
 
         in.position(pos);
 
@@ -108,7 +108,7 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream {
             return null;
         }
 
-        FieldRange range = fieldRange(fieldName);
+        FieldRange range = fieldRange(fieldName, pos);
 
         F field = null;
 
@@ -133,10 +133,11 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream {
      * Returns field offset in the byte stream.
      *
      * @param fieldName Field name.
+     * @param start Object's start offset.
      * @return positive range or {@code null} if the object doesn't have such a field.
      * @throws IOException in case of error.
      */
-    private FieldRange fieldRange(String fieldName) throws IOException {
+    private FieldRange fieldRange(String fieldName, int start) throws IOException {
         int fieldId = resolveFieldId(fieldName);
 
         int typeId = readInt();
@@ -177,7 +178,7 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream {
                 //object header len: 1 - for type, 4 - for type ID, 2 - for checksum.
                 fieldOff += 1 + 4 + clsNameLen + 2;
 
-                return new FieldRange(fieldOff, info.len == VARIABLE_LEN ? in.readShort() : info.len);
+                return new FieldRange(start + fieldOff, info.len == VARIABLE_LEN ? in.readShort() : info.len);
             }
             else
                 fieldOff += info.len == VARIABLE_LEN ? in.readShort() : info.len;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java
index 77e48c1..d9f85aa 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java
@@ -108,7 +108,22 @@ public class IgniteCacheOptimizedMarshallerExtQuerySelfTest extends GridCacheAbs
      * @throws Exception In case of error.
      */
     public void testNestedFieldsQuery() throws Exception {
+        IgniteCache<Integer, Person> cache = grid(0).cache(null);
+
+        Collection<Cache.Entry<Integer, Person>> entries = cache.query(new SqlQuery<Integer, Person>(
+            "Person", "name is not null AND (zip = 1 OR zip = 2)")).getAll();
+
+        assertEquals(2, entries.size());
 
+        for (Cache.Entry<Integer, Person> entry : entries) {
+            int id = entry.getKey();
+            Person p = entry.getValue();
+
+            assertEquals("Person " + id, p.name);
+            assertEquals((id + 1) * 100, p.salary);
+            assertEquals("Street " + id, p.address.street);
+            assertEquals(id, p.address.zip);
+        }
     }
 
     /**