I'm converting code from objectify 4 to 5.
Previously I was saving an @Entity
containing a class that contained
List<List<String>> listOfListOfStrings;
With version 5 I get a SaveException:
com.googlecode.objectify.SaveException:
Error saving com.timmacp.server.OfyEntityClass@3d627804:
listOfListOfStrings: java.util.ArrayList is not a supported property type`
same problem with arrays of arrays.
Here is some code I've used to test, MemberClass
just contains a String
.
@Entity
public class OfyEntityClass {
@Id
private Long ID;
List<List<MemberClass>> memberClassObjects;
public OfyEntityClass(){
memberClassObjects=new ArrayList<List<MemberClass>>(8);
List<MemberClass> l=new ArrayList<MemberClass>(8);
MemberClass memberClassObject=new MemberClass();
l.add(memberClassObject);
memberClassObjects.add(l);
}
}
A workaround seems to be to put each List
level in its own class, but this seems strange as the docs state that "Many limitations of Objectify4 no longer apply to Objectify5: Nesting of collections of embedded objects is unrestricted."
Update: some of the fields were annotated with @Serialize
in the ofy4 version. I'd removed these thinking they were not required in ofy5 so that explains the difference. Still wondering if its possible to do this without @Serialize
. Wrapper classes seem to work to simulate a List<List<String>
but not for more complex nesting.
Update 2:
with v5, won't work with a recursive class? ie if Thing has a field of type
List<Thing>
then (so far) register fails: stack trace looks like infinite repetition of:
at com.googlecode.objectify.impl.translate.Translators.create(Translators.java:138)
at com.googlecode.objectify.impl.translate.Translators.get(Translators.java:117)
at com.googlecode.objectify.impl.translate.CreateContext.getTranslator(CreateContext.java:27)
at com.googlecode.objectify.impl.translate.CollectionTranslatorFactory.create(CollectionTranslatorFactory.java:38)
at com.googlecode.objectify.impl.translate.Translators.create(Translators.java:138)
at com.googlecode.objectify.impl.translate.Translators.get(Translators.java:117)
at com.googlecode.objectify.impl.translate.CreateContext.getTranslator(CreateContext.java:27)
at com.googlecode.objectify.impl.translate.ClassPopulator.<init>(ClassPopulator.java:88)
at com.googlecode.objectify.impl.translate.ClassTranslatorFactory.createEmbeddedClassTranslator(ClassTranslatorFactory.java:75)
at com.googlecode.objectify.impl.translate.ClassTranslatorFactory.create(ClassTranslatorFactory.java:50)
at com.googlecode.objectify.impl.translate.ClassTranslatorFactory.create(ClassTranslatorFactory.java:36)
Or maybe there's a way to specify the number of recursion levels for the translators?
Primary Objectify author here.
Objectify4 should not be able to save a field of type
List<List<String>>
. I can't even imagine what that would do, or why it would work. There are no tests around it. Historically, GAE only allowed storing a simple collection of scalar values in entities. At some point they expanded that by providingEmbeddedEntity
, but that is something different. I haven't tried storing aList<List<String>>
manually with the low-level api, but if it works, that's something new that Google has not announced nor have they documented it. Nor does there appear to be any way of defining structures like this in GAE/Python (db or ndb).So I don't know what to tell you. If you tell me you have a working application which stores and retrieves a
List<List<String>>
field - then this is something new. How long have you had this deployed?