Search code examples
google-app-enginedatastoreobjectifyexpando

Objectify embedded maps fail to retrieve


I am using Objectify as a data access layer in my GoogleAppEngine hosted application.

The problem comes when I try to persist a map. My bean looks like this:

@Entity
@Cached
class MyBean{
    @Id 
    private Long id;
    @Embedded
    Map<String, String> parameters = new HashMap<String, String>();

    public MyBean(){}

    //getters and setters below
}

First of all note that the map 'parameters' is not private, it was throwing a JRE exception. When saving the map everything goes well. When retreiving it from the DataStore it fails.

My workaround is to use the @Serialized annotation. This is just a workaround since what I want to acheive is to use the expando feature of GAE Datastore.

According to the objectify doc I'm doing the right operations.

Exception details:

Caused by: java.lang.NullPointerException at com.googlecode.objectify.impl.Transmog.loadSingleValue(Transmog.java:364) at com.googlecode.objectify.impl.load.EmbeddedMapSetter.safeSet(EmbeddedMapSetter.java:65) at com.googlecode.objectify.impl.load.CollisionDetectingSetter.set(CollisionDetectingSetter.java:37) at com.googlecode.objectify.impl.Transmog.loadSingleValue(Transmog.java:359) at com.googlecode.objectify.impl.Transmog.load(Transmog.java:340) at com.googlecode.objectify.impl.ConcreteEntityMetadata.toObject(ConcreteEntityMetadata.java:203) at com.googlecode.objectify.impl.QueryImpl$ToObjectIterator.translate(QueryImpl.java:668) at com.googlecode.objectify.impl.QueryImpl$ToObjectIterator.translate(QueryImpl.java:657) at com.googlecode.objectify.util.TranslatingIterator.next(TranslatingIterator.java:35)


Solution

  • Embedded maps were poorly supported in Objectify3, and should not have been publicly announced. The section on @Embedded Map has been removed from the Objectify3 documentation.

    Objectify4 supports maps extensively, including these expando-style maps:

    • Map (or any primitive)
    • Map (key references)
    • Map (embedded classes

    In addition, there is a @Mapify annotation that lets you take a normal collection of objects, pick one property out as a key, and store that as a Map.

    Unfortunately Objectify4's documentation is not ready at this time. However, the source code is in active use by several parties. If you feel daring, build from trunk.