You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2015/07/20 17:32:38 UTC

[2/6] zest-qi4j git commit: ZEST-69 Fix and assert NamedAssociation equals/hashcode & serialization

ZEST-69 Fix and assert NamedAssociation equals/hashcode & serialization


Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/3e3e89d8
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/3e3e89d8
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/3e3e89d8

Branch: refs/heads/develop
Commit: 3e3e89d824772095925cbc89a1868abbdadb2bd6
Parents: 7b827e6
Author: Paul Merlin <pa...@apache.org>
Authored: Mon Jul 20 14:31:27 2015 +0200
Committer: Paul Merlin <pa...@apache.org>
Committed: Mon Jul 20 16:44:46 2015 +0200

----------------------------------------------------------------------
 .../runtime/entity/EntityStateInstance.java     |  2 +-
 .../value/NamedAssociationValueState.java       | 21 ------
 .../org/qi4j/runtime/value/ValueInstance.java   | 12 ++++
 .../qi4j/runtime/value/ValueStateInstance.java  |  5 +-
 .../org/qi4j/runtime/value/ValueStateModel.java |  2 +-
 .../association/AssociationEqualityTest.java    | 75 ++++++++++++++++++--
 .../qi4j/spi/value/ValueSerializerAdapter.java  |  2 +-
 ...AbstractValueCompositeSerializationTest.java | 14 +++-
 .../stax/StaxValueDeserializer.java             | 16 +++--
 9 files changed, 110 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateInstance.java
index d44a3f9..505509b 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateInstance.java
@@ -248,7 +248,7 @@ public final class EntityStateInstance
             constraints.checkConstraints( association.get() );
         }
 
-        // TODO Should ManyAssociations be checked too?
+        // TODO Should ManyAssociations and NamedAssociations be checked too?
     }
 
     private Map<AccessibleObject, Object> state()

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/runtime/src/main/java/org/qi4j/runtime/value/NamedAssociationValueState.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/NamedAssociationValueState.java b/core/runtime/src/main/java/org/qi4j/runtime/value/NamedAssociationValueState.java
index 694be18..4f3030d 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/NamedAssociationValueState.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/NamedAssociationValueState.java
@@ -81,25 +81,4 @@ public class NamedAssociationValueState
     {
         return references.keySet().iterator();
     }
-
-    @Override
-    public boolean equals( Object o )
-    {
-        if( this == o )
-        {
-            return true;
-        }
-        if( o == null || getClass() != o.getClass() )
-        {
-            return false;
-        }
-        NamedAssociationValueState strings = (NamedAssociationValueState) o;
-        return references.equals( strings.references );
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return references.hashCode();
-    }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
index fc7c95e..3b11c04 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
@@ -21,6 +21,7 @@ import org.qi4j.api.composite.CompositeInstance;
 import org.qi4j.api.value.ValueComposite;
 import org.qi4j.runtime.association.AssociationModel;
 import org.qi4j.runtime.association.ManyAssociationModel;
+import org.qi4j.runtime.association.NamedAssociationModel;
 import org.qi4j.runtime.composite.MixinsInstance;
 import org.qi4j.runtime.composite.TransientInstance;
 import org.qi4j.runtime.property.PropertyInstance;
@@ -124,6 +125,12 @@ public final class ValueInstance
             state().manyAssociationFor( associationDescriptor.accessor() )
                 .setAssociationInfo( associationDescriptor.getBuilderInfo() );
         }
+
+        for( NamedAssociationModel associationDescriptor : descriptor().state().namedAssociations() )
+        {
+            state().namedAssociationFor( associationDescriptor.accessor() )
+                .setAssociationInfo( associationDescriptor.getBuilderInfo() );
+        }
     }
 
     /**
@@ -148,6 +155,11 @@ public final class ValueInstance
         {
             state().manyAssociationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor );
         }
+
+        for( NamedAssociationModel associationDescriptor : descriptor().state().namedAssociations() )
+        {
+            state().namedAssociationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor );
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
index 3d41470..c66734f 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Map;
 import org.qi4j.api.association.AssociationDescriptor;
 import org.qi4j.api.association.AssociationStateHolder;
-import org.qi4j.api.association.NamedAssociation;
 import org.qi4j.api.entity.EntityReference;
 import org.qi4j.api.property.PropertyDescriptor;
 import org.qi4j.runtime.association.AssociationInfo;
@@ -181,7 +180,7 @@ public final class ValueStateInstance
 
     @Override
     @SuppressWarnings( "unchecked" )
-    public <T> NamedAssociation<T> namedAssociationFor( AccessibleObject accessor )
+    public <T> NamedAssociationInstance<T> namedAssociationFor( AccessibleObject accessor )
     {
         NamedAssociationInstance<T> namedAssociation = (NamedAssociationInstance<T>) namedAssociations.get( accessor );
 
@@ -194,7 +193,7 @@ public final class ValueStateInstance
     }
 
     @Override
-    public Iterable<? extends NamedAssociation<?>> allNamedAssociations()
+    public Iterable<? extends NamedAssociationInstance<?>> allNamedAssociations()
     {
         return namedAssociations.values();
     }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
index d3f8060..76e4bb8 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
@@ -105,7 +105,7 @@ public final class ValueStateModel
     }
 
     @Override
-    public Iterable<? extends AssociationDescriptor> namedAssociations()
+    public Iterable<NamedAssociationModel> namedAssociations()
     {
         return namedAssociationsModel.namedAssociations();
     }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/runtime/src/test/java/org/qi4j/runtime/association/AssociationEqualityTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/qi4j/runtime/association/AssociationEqualityTest.java b/core/runtime/src/test/java/org/qi4j/runtime/association/AssociationEqualityTest.java
index 1c3852e..7aabc8c 100644
--- a/core/runtime/src/test/java/org/qi4j/runtime/association/AssociationEqualityTest.java
+++ b/core/runtime/src/test/java/org/qi4j/runtime/association/AssociationEqualityTest.java
@@ -20,6 +20,7 @@ import org.junit.Test;
 import org.qi4j.api.association.Association;
 import org.qi4j.api.association.AssociationDescriptor;
 import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.association.NamedAssociation;
 import org.qi4j.api.common.Optional;
 import org.qi4j.api.unitofwork.UnitOfWork;
 import org.qi4j.api.value.ValueBuilder;
@@ -33,7 +34,7 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assert.assertThat;
 
 /**
- * Assert that Association and ManyAssociation equals/hashcode methods combine AssociationDescriptor and State.
+ * Assert that Association, ManyAssociation and NamedAssociation equals/hashcode methods combine AssociationDescriptor and State.
  */
 public class AssociationEqualityTest
     extends AbstractQi4jTest
@@ -62,6 +63,8 @@ public class AssociationEqualityTest
         Association<AnEntity> anEntity();
 
         ManyAssociation<AnEntity> manyEntities();
+
+        NamedAssociation<AnEntity> namedEntities();
     }
 
     public interface OtherWithAssociations
@@ -71,6 +74,8 @@ public class AssociationEqualityTest
         Association<AnEntity> anEntity();
 
         ManyAssociation<AnEntity> manyEntities();
+
+        NamedAssociation<AnEntity> namedEntities();
     }
 
     //
@@ -87,10 +92,12 @@ public class AssociationEqualityTest
             SomeWithAssociations some = buildSomeWithAssociation( anEntity );
             AssociationDescriptor someAssocDesc = qi4j.api().associationDescriptorFor( some.anEntity() );
             AssociationDescriptor someManyAssocDesc = qi4j.api().associationDescriptorFor( some.manyEntities() );
+            AssociationDescriptor someNamedAssocDesc = qi4j.api().associationDescriptorFor( some.namedEntities() );
 
             SomeWithAssociations some2 = buildSomeWithAssociation( anEntity );
             AssociationDescriptor some2AssocDesc = qi4j.api().associationDescriptorFor( some2.anEntity() );
             AssociationDescriptor some2ManyAssocDesc = qi4j.api().associationDescriptorFor( some2.manyEntities() );
+            AssociationDescriptor some2NamedAssocDesc = qi4j.api().associationDescriptorFor( some2.namedEntities() );
 
             assertThat( "AssociationDescriptor equal",
                         someAssocDesc,
@@ -104,6 +111,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociationDescriptor hashcode equal",
                         someManyAssocDesc.hashCode(),
                         equalTo( some2ManyAssocDesc.hashCode() ) );
+            assertThat( "NamedAssociationDescriptor equal",
+                        someNamedAssocDesc,
+                        equalTo( some2NamedAssocDesc ) );
+            assertThat( "NamedAssociationDescriptor hashcode equal",
+                        someNamedAssocDesc.hashCode(),
+                        equalTo( some2NamedAssocDesc.hashCode() ) );
         }
         finally
         {
@@ -120,10 +133,12 @@ public class AssociationEqualityTest
             SomeWithAssociations some = buildSomeWithAssociation( uow.newEntity( AnEntity.class ) );
             AssociationDescriptor someAssocDesc = qi4j.api().associationDescriptorFor( some.anEntity() );
             AssociationDescriptor someManyAssocDesc = qi4j.api().associationDescriptorFor( some.manyEntities() );
+            AssociationDescriptor someNamedAssocDesc = qi4j.api().associationDescriptorFor( some.namedEntities() );
 
             SomeWithAssociations some2 = buildSomeWithAssociation( uow.newEntity( AnEntity.class ) );
             AssociationDescriptor some2AssocDesc = qi4j.api().associationDescriptorFor( some2.anEntity() );
             AssociationDescriptor some2ManyAssocDesc = qi4j.api().associationDescriptorFor( some2.manyEntities() );
+            AssociationDescriptor some2NamedAssocDesc = qi4j.api().associationDescriptorFor( some2.namedEntities() );
 
             assertThat( "AssociationDescriptor equal",
                         someAssocDesc,
@@ -137,6 +152,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociationDescriptor hashcode equal",
                         someManyAssocDesc.hashCode(),
                         equalTo( some2ManyAssocDesc.hashCode() ) );
+            assertThat( "NamedAssociationDescriptor equal",
+                        someNamedAssocDesc,
+                        equalTo( some2NamedAssocDesc ) );
+            assertThat( "NamedAssociationDescriptor hashcode equal",
+                        someNamedAssocDesc.hashCode(),
+                        equalTo( some2NamedAssocDesc.hashCode() ) );
         }
         finally
         {
@@ -155,10 +176,12 @@ public class AssociationEqualityTest
             SomeWithAssociations some = buildSomeWithAssociation( anEntity );
             AssociationDescriptor someAssocDesc = qi4j.api().associationDescriptorFor( some.anEntity() );
             AssociationDescriptor someManyAssocDesc = qi4j.api().associationDescriptorFor( some.manyEntities() );
+            AssociationDescriptor someNamedAssocDesc = qi4j.api().associationDescriptorFor( some.namedEntities() );
 
             OtherWithAssociations other = buildOtherWithAssociation( anEntity );
             AssociationDescriptor otherAssocDesc = qi4j.api().associationDescriptorFor( other.anEntity() );
-            AssociationDescriptor some2ManyAssocDesc = qi4j.api().associationDescriptorFor( other.manyEntities() );
+            AssociationDescriptor otherManyAssocDesc = qi4j.api().associationDescriptorFor( other.manyEntities() );
+            AssociationDescriptor otherNamedAssocDesc = qi4j.api().associationDescriptorFor( other.namedEntities() );
 
             assertThat( "AssociationDescriptor not equal",
                         someAssocDesc,
@@ -168,10 +191,16 @@ public class AssociationEqualityTest
                         not( equalTo( otherAssocDesc.hashCode() ) ) );
             assertThat( "ManyAssociationDescriptor not equal",
                         someManyAssocDesc,
-                        not( equalTo( some2ManyAssocDesc ) ) );
+                        not( equalTo( otherManyAssocDesc ) ) );
             assertThat( "ManyAssociationDescriptor hashcode not equal",
                         someManyAssocDesc.hashCode(),
-                        not( equalTo( some2ManyAssocDesc.hashCode() ) ) );
+                        not( equalTo( otherManyAssocDesc.hashCode() ) ) );
+            assertThat( "NamedAssociationDescriptor not equal",
+                        someNamedAssocDesc,
+                        not( equalTo( otherNamedAssocDesc ) ) );
+            assertThat( "NamedAssociationDescriptor hashcode not equal",
+                        someNamedAssocDesc.hashCode(),
+                        not( equalTo( otherNamedAssocDesc.hashCode() ) ) );
         }
         finally
         {
@@ -203,6 +232,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociation State hashcode not equal",
                         some.manyEntities().toList().hashCode(),
                         not( equalTo( some2.manyEntities().toList().hashCode() ) ) );
+            assertThat( "NamedAssociation State not equal",
+                        some.namedEntities().toMap(),
+                        not( equalTo( some2.namedEntities().toMap() ) ) );
+            assertThat( "NamedAssociation State hashcode not equal",
+                        some.namedEntities().toMap().hashCode(),
+                        not( equalTo( some2.namedEntities().toMap().hashCode() ) ) );
         }
         finally
         {
@@ -233,6 +268,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociation State hashcode equal",
                         some.manyEntities().toList().hashCode(),
                         equalTo( other.manyEntities().toList().hashCode() ) );
+            assertThat( "NamedAssociation State equal",
+                        some.namedEntities().toMap(),
+                        equalTo( other.namedEntities().toMap() ) );
+            assertThat( "NamedAssociation State hashcode equal",
+                        some.namedEntities().toMap().hashCode(),
+                        equalTo( other.namedEntities().toMap().hashCode() ) );
         }
         finally
         {
@@ -266,6 +307,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociation hashcode equal",
                         some.manyEntities().hashCode(),
                         equalTo( some2.manyEntities().hashCode() ) );
+            assertThat( "NamedAssociation equal",
+                        some.namedEntities(),
+                        equalTo( some2.namedEntities() ) );
+            assertThat( "NamedAssociation hashcode equal",
+                        some.namedEntities().hashCode(),
+                        equalTo( some2.namedEntities().hashCode() ) );
         }
         finally
         {
@@ -294,6 +341,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociation hashcode not equal",
                         some.manyEntities().hashCode(),
                         not( equalTo( some2.manyEntities().hashCode() ) ) );
+            assertThat( "NamedAssociation not equal",
+                        some.namedEntities(),
+                        not( equalTo( some2.namedEntities() ) ) );
+            assertThat( "NamedAssociation hashcode not equal",
+                        some.namedEntities().hashCode(),
+                        not( equalTo( some2.namedEntities().hashCode() ) ) );
         }
         finally
         {
@@ -324,6 +377,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociation hashcode not equal",
                         some.manyEntities().hashCode(),
                         not( equalTo( other.manyEntities().hashCode() ) ) );
+            assertThat( "NamedAssociation not equal",
+                        some.namedEntities(),
+                        not( equalTo( other.namedEntities() ) ) );
+            assertThat( "NamedAssociation hashcode not equal",
+                        some.namedEntities().hashCode(),
+                        not( equalTo( other.namedEntities().hashCode() ) ) );
         }
         finally
         {
@@ -352,6 +411,12 @@ public class AssociationEqualityTest
             assertThat( "ManyAssociation hashcode not equal",
                         some.manyEntities().hashCode(),
                         not( equalTo( other.manyEntities().hashCode() ) ) );
+            assertThat( "NamedAssociation not equal",
+                        some.namedEntities(),
+                        not( equalTo( other.namedEntities() ) ) );
+            assertThat( "NamedAssociation hashcode not equal",
+                        some.namedEntities().hashCode(),
+                        not( equalTo( other.namedEntities().hashCode() ) ) );
         }
         finally
         {
@@ -369,6 +434,7 @@ public class AssociationEqualityTest
             ValueBuilder<SomeWithAssociations> builder = module.newValueBuilder( SomeWithAssociations.class );
             builder.prototype().anEntity().set( associated );
             builder.prototype().manyEntities().add( associated );
+            builder.prototype().namedEntities().put( "someKey", associated );
             some = builder.newInstance();
         }
         return some;
@@ -381,6 +447,7 @@ public class AssociationEqualityTest
             ValueBuilder<OtherWithAssociations> builder = module.newValueBuilder( OtherWithAssociations.class );
             builder.prototype().anEntity().set( associated );
             builder.prototype().manyEntities().add( associated );
+            builder.prototype().namedEntities().put( "someKey", associated );
             some = builder.newInstance();
         }
         return some;

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
index 004745a..6f17569 100644
--- a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
+++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
@@ -479,7 +479,7 @@ public abstract class ValueSerializerAdapter<OutputType>
                 onFieldStart( output, name );
                 onValueStart( output );
                 EntityReference ref = namedAssociation.referenceOf( name );
-                onValue( output, ( (Identity) namedAssociation.get( name ) ).identity().get() );
+                onValue( output, ref.identity() );
                 onValueEnd( output );
                 onFieldEnd( output );
             }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java b/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java
index 01d2f51..4bece76 100644
--- a/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java
+++ b/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java
@@ -32,6 +32,7 @@ import org.junit.Test;
 import org.junit.rules.TestName;
 import org.qi4j.api.association.Association;
 import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.association.NamedAssociation;
 import org.qi4j.api.common.Optional;
 import org.qi4j.api.common.UseDefaults;
 import org.qi4j.api.common.Visibility;
@@ -58,7 +59,6 @@ import static org.junit.Assert.assertThat;
 /**
  * Assert that ValueSerialization behaviour on ValueComposites is correct.
  */
-// TODO Assert Association, ManyAssociation and NamedAssociation serialization behaviour!
 // TODO Assert Arrays behaviour!
 // TODO Assert Generics behaviour!
 public abstract class AbstractValueCompositeSerializationTest
@@ -105,7 +105,7 @@ public abstract class AbstractValueCompositeSerializationTest
             SomeValue some2 = module.newValueFromSerializedState( SomeValue.class, stateString );
 
             assertThat( "Same value toString", some.toString(), equalTo( some2.toString() ) );
-//            assertThat( "Same value", some, equalTo( some2 ) );
+            assertThat( "Same value", some, equalTo( some2 ) );
             assertThat( "Same JSON value toString", stateString, equalTo( some2.toString() ) );
             assertThat( "Same JSON value", some.customFoo().get() instanceof CustomFooValue, is( true ) );
             assertThat( "Same JSON value explicit", some.customFooValue().get() instanceof CustomFooValue, is( true ) );
@@ -193,6 +193,10 @@ public abstract class AbstractValueCompositeSerializationTest
         proto.barManyAssociation().add( buildBarEntity( "bazar TWO in barManyAssociation" ) );
         proto.barEntityManyAssociation().add( buildBarEntity( "bazar ONE in barEntityManyAssociation" ) );
         proto.barEntityManyAssociation().add( buildBarEntity( "bazar TWO in barEntityManyAssociation" ) );
+        proto.barNamedAssociation().put( "bazar", buildBarEntity( "bazar in barNamedAssociation" ) );
+        proto.barNamedAssociation().put( "cathedral", buildBarEntity( "cathedral in barNamedAssociation" ) );
+        proto.barEntityNamedAssociation().put( "bazar", buildBarEntity( "bazar in barEntityNamedAssociation" ) );
+        proto.barEntityNamedAssociation().put( "cathedral", buildBarEntity( "cathedral in barEntityNamedAssociation" ) );
 
         return builder.newInstance();
     }
@@ -309,6 +313,12 @@ public abstract class AbstractValueCompositeSerializationTest
         ManyAssociation<Bar> barManyAssociation();
 
         ManyAssociation<BarEntity> barEntityManyAssociation();
+
+        NamedAssociation<Bar> barNamedAssociationEmpty();
+
+        NamedAssociation<Bar> barNamedAssociation();
+
+        NamedAssociation<BarEntity> barEntityNamedAssociation();
     }
 
     public interface SpecificCollection

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/3e3e89d8/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueDeserializer.java
----------------------------------------------------------------------
diff --git a/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueDeserializer.java b/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueDeserializer.java
index 2051eb7..6c61ffb 100644
--- a/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueDeserializer.java
+++ b/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueDeserializer.java
@@ -432,14 +432,18 @@ public class StaxValueDeserializer
         {
             return;
         }
-        NodeList entriesNodes = inputNode.getChildNodes();
-        for( int idx = 0; idx < entriesNodes.getLength(); idx++ )
+        if( !"object".equals( inputNode.getLocalName() ) )
         {
-            Node entryNode = entriesNodes.item( idx );
-            String key  = ((Element) entryNode).getTagName();
-            V value = getObjectFieldValue( entryNode, "value", valueDeserializer );
-            if( key != null )
+            throw new ValueSerializationException( "Expected an <object/> but got " + inputNode );
+        }
+        NodeList fieldsNodes = inputNode.getChildNodes();
+        for( int idx = 0; idx < fieldsNodes.getLength(); idx++ )
+        {
+            Node fieldNode = fieldsNodes.item( idx );
+            String key = getDirectChildNode( fieldNode, "name" ).getTextContent();
+            if( key != null && key.length() > 0 )
             {
+                V value = getObjectFieldValue( inputNode, key, valueDeserializer );
                 map.put( key, value );
             }
         }