Embedded Map: should it work?

18 views
Skip to first unread message

Sébastien Tromp

unread,
Apr 16, 2012, 10:08:23 AM4/16/12
to twig-p...@googlegroups.com
Hello,

I have the following test case (attached):

public class Instance implements Serializable {

    @GaeKey
    private String id;

    @Embedded
    private Map<Integer, Integer> map;
}

        final Instance instance = new Instance();
        final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        map.put(0, 100);
        map.put(1, 60);
        instance.setMap(map);

        final ObjectDatastore datastore = new AnnotationObjectDatastore();
        // Exception here
        datastore.store(map);

And I get an exception
          java.lang.IllegalStateException: Final field final float java.util.HashMap.loadFactor cannot be stored

Do you have any idea of what I am doing wrong?

Instance.java
TestEmbeddedMapPersistence.java
LocalDatastoreTestCase.java

John Patterson

unread,
Apr 16, 2012, 11:33:22 PM4/16/12
to twig-p...@googlegroups.com


You do not need the @Embedded annotation on the map because there is a special MapTranslator that automatically stores maps as name-value pairs. @Embedded tells Twig to look at the fields inside the instance (in this case a HashMap) and store the field values which causes a problem because one of them is final.

John

Sébastien Tromp

unread,
Apr 17, 2012, 6:08:02 AM4/17/12
to twig-p...@googlegroups.com
Thanks John, did not know that :)

Sébastien Tromp

unread,
Apr 17, 2012, 8:44:57 AM4/17/12
to twig-p...@googlegroups.com
And by the way, I tried with a Map<String, Set<String>>, and got a similar exception :

     java.lang.IllegalStateException: Final field private final int java.lang.String.count cannot be stored

both with @Embedded and without. Do I have to write a custom field translator to handle this kind of case?

2012/4/17 Sébastien Tromp <sebasti...@gmail.com>

John Patterson

unread,
Apr 18, 2012, 4:04:57 AM4/18/12
to twig-p...@googlegroups.com
I just added a test case with exactly this type and it seems to work.

If you post the entire exception perhaps I can see what is going wrong.  It appears that you are @Embedding a String.

My test passed with the latest source code so I am not sure if a bug existed that is not fixed.

Sébastien Tromp

unread,
Apr 18, 2012, 6:09:03 AM4/18/12
to twig-p...@googlegroups.com
On Wed, Apr 18, 2012 at 10:04 AM, John Patterson <jdpat...@gmail.com> wrote:
I just added a test case with exactly this type and it seems to work.

If you post the entire exception perhaps I can see what is going wrong.  It appears that you are @Embedding a String.

My test passed with the latest source code so I am not sure if a bug existed that is not fixed.
 
The test case is the same as the one joined, except that the Map is now a Map<String, Set<String>>

        final Instance instance = new Instance();
        final Map<String, Set<String>> map = new HashMap<String, Set<String>>();
        map.put("0", new HashSet<String>(Arrays.asList(new String[] { "100" })));
        map.put("1", new HashSet<String>(Arrays.asList(new String[] { "60" })));
        instance.setMap(map);

        final ObjectDatastore datastore = new AnnotationObjectDatastore();
        datastore.store(instance);

and Instance being

public class Instance implements Serializable {
    // No annotation
    private Map<String, Set<String>> map;
}

The full exception stack I get is:

java.lang.IllegalStateException: Final field private final int java.lang.String.count cannot be stored
at com.google.code.twig.annotation.AnnotationConfiguration.store(AnnotationConfiguration.java:126)
at com.google.code.twig.standard.TranslatorObjectDatastore$ConfigurationFieldTranslator.stored(TranslatorObjectDatastore.java:673)
at com.google.code.twig.translator.FieldTranslator.encode(FieldTranslator.java:333)
at com.google.code.twig.standard.StandardCommonStoreCommand.instanceToEntity(StandardCommonStoreCommand.java:284)
at com.google.code.twig.standard.StandardCommonStoreCommand.instancesToEntities(StandardCommonStoreCommand.java:197)
at com.google.code.twig.standard.StandardMultipleStoreCommand.now(StandardMultipleStoreCommand.java:31)
at com.google.code.twig.standard.RelationTranslator.instancesToKeys(RelationTranslator.java:189)
at com.google.code.twig.standard.RelationTranslator.access$000(RelationTranslator.java:26)
at com.google.code.twig.standard.RelationTranslator$1.get(RelationTranslator.java:131)
at com.google.code.twig.standard.RelationTranslator$1.get(RelationTranslator.java:125)
at com.google.code.twig.standard.StandardEncodeCommand.dereferencePropertyValue(StandardEncodeCommand.java:58)
at com.google.code.twig.standard.StandardEncodeCommand.transferProperties(StandardEncodeCommand.java:41)
at com.google.code.twig.standard.StandardCommonStoreCommand.instanceToEntity(StandardCommonStoreCommand.java:294)
at com.google.code.twig.standard.StandardSingleStoreCommand.now(StandardSingleStoreCommand.java:58)
at com.google.code.twig.standard.TranslatorObjectDatastore.store(TranslatorObjectDatastore.java:161)
at com.fiveorbs.server.access.embeddedmap.TestEmbeddedMapPersistence.testEmbeddedMap(TestEmbeddedMapPersistence.java:27) 

John Patterson

unread,
Apr 18, 2012, 7:17:23 AM4/18/12
to twig-p...@googlegroups.com
Something is stopping String being recognised as a native type.  Instead the set of strings is being treated as a set of related objects (with their own Entities).  I can see this because RelationTranslator is being used to store the Set.

This is not the behaviour I see when I run this test case (I added it to an existing Map test):


created.stingToStringSet = new HashMap<String, Set<String>>();
Set<String> values = new HashSet<String>();
values.add("There");
created.stingToStringSet.put("Hi", values);

AnnotationObjectDatastore datastore = new AnnotationObjectDatastore();
Key key = datastore.store(created);
datastore.disassociateAll();
Object loaded = datastore.load(key);
Assert.assertEquals(created, loaded);


So I think something is wrong with your translator setup.  Do you customise it?  Also, make sure you get the latest code to test with.

Sébastien Tromp

unread,
Apr 19, 2012, 3:47:31 AM4/19/12
to twig-p...@googlegroups.com
I have no custom translator setup, but I am not using the latest version (mine is two months old, before you huge commit).
I don't plan on updating right now, but I can live without it for the moment. I'll let you know once my twig code is up-to-date.
Reply all
Reply to author
Forward
0 new messages