As a result the data being mapped into the application had to some extent to match the objects which had produced it. As a result I have a SortedMap field in one of my data objects.
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class WavaBase implements Comparable <WavaBase> {
@PrimaryKey
@Persistent
private String id;
@Persistent
private String sex;
@Persistent
private Double standardInSeconds;
@Persistent
private String distance;
@Persistent
private Double distanceInKilometers;
private SortedMap<Integer,WavaData> wavaData;
@Persistent(mappedBy="wavaBase")
private SortedSet<WavaData> wavaDataSet;
...
}
The sorted map is not annotated as @Persistent but here is the gotcha. GAE will still attempt to persist it resulting in a most unhelpful warning
java.lang.UnsupportedOperationException: FK Maps not supported.
at org.datanucleus.store.appengine.DatastoreManager.newFKMapStore(DatastoreManager.java:401)
at org.datanucleus.store.mapped.MappedStoreManager.getBackingStoreForMap(MappedStoreManager.java:766)
at org.datanucleus.store.mapped.MappedStoreManager.getBackingStoreForField(MappedStoreManager.java:637)
at org.datanucleus.sco.backed.SortedMap.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
Looking at the trace you can see that datanucleus is attemting to deal with the SortedSet even though it is not marked for persistence.
To ensure that a private member of a @PersistenceCapable class is not processed by the persistence store you need to "explicitly" mark the member as @NotPersistent, this tells the persistence layer to ignore the member.
So the class becomes
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class WavaBase implements Comparable <WavaBase> {
@PrimaryKey
@Persistent
private String id;
@Persistent
private String sex;
@Persistent
private Double standardInSeconds;
@Persistent
private String distance;
@Persistent
private Double distanceInKilometers;
@NotPersistent
private SortedMap<Integer,WavaData> wavaData;
@Persistent(mappedBy="wavaBase")
private SortedSet<WavaData> wavaDataSet;
...
}
There may be a way to switch the default handling of members of a @PersistenceCapable class so that members need to be explicitly included in persistence rather than excluded, but I haven't found it yet.
wow, thanks, good catch. some google engineers are monkeys and wasted everyone's time w/ poor coding. good thing you posted this posting.
ReplyDeleteGreat, Thank you very much for your great support.
ReplyDelete