In that case, do you need the child to be an Entity at all? Perhaps you could simply embed it in the parent.
Not too sure about the JDO case, I think it might be impossible to embed a collection unless it is of "native" values. But with Twig you can embed an entire collection of child objects and they can be automatically encoded as multi-value properties that you can then query on. It does this using the order of multi valued properties. For example: name="Order name" date="1 Dec 2009" items.name=["An item", "Another Item", "Yet another item"] items.price=[3.45, 1.67, 8.98] You can now filter (or sort) by a child property and partent property. You cannot find a parent with a certain price AND a name but your case sounds fine. Don't worry, Twig encodes and decodes the objects. This only works for one level of collection; if an item had a collection of parts Twig can still encode it but not as ordered multi-value properties. John 2009/12/22 Eugene Kuleshov <ekules...@gmail.com> > On Dec 19, 2:56 am, jd <jdpatter...@gmail.com> wrote: > > > Could you not split your query into two? The first to find the parent > > and the second to return all children with an ancestor query. > > In my case the main filtering criteria is actually by one of the > child's attributes, but then I need to sort the results and present > them using some of the parent's attributes. For example, with Order > and OrderItem model, find all OrderItems that include the given part > number and then sort the result according to the Order's date. So, I > do need to preserve parent-child relationship, but don't want to > execute N+1 queries (one for each parent referenced from the found > children). > > Also, I would like to maintain parent-child relationship, so entity > groups are handled automatically (so I won't have to manually create > foreign keys), i.e. I can process all parent-child chunks in one > transaction. > > Thanks > > Eugene > > > > On Dec 19, 3:58 am, Eugene Kuleshov <ekules...@gmail.com> wrote: > > > > > It shouldn't be needed, since according to the docs [1], the Key > > > type is only required to record parent relation in the child. > > > But I tried it anyways and got pretty much the same exception: > > > > > Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 > > > at > org.datanucleus.store.appengine.DatastoreTable.initializeNonPK > > > (DatastoreTable.java:356) > > > at org.datanucleus.store.appengine.DatastoreTable.buildMapping > > > (DatastoreTable.java:285) > > > at > org.datanucleus.store.appengine.DatastoreManager.buildStoreData > > > (DatastoreManager.java:405) > > > ... > > > > > regards, > > > Eugene > > > > > [1] > http://code.google.com/appengine/docs/java/datastore/creatinggettinga... > > > > > On Dec 18, 2:33 pm, Rusty Wright <rwright.li...@gmail.com> wrote: > > > > > > Try making the parent's primary key be Key instead of String. > > > > > > Eugene Kuleshov wrote: > > > > > I am using the app engine SDK 1.3.0 with the latest Google > Eclipse > > > > > plugin. > > > > > > > Currently, in order to be able to run queries on attributes of > the > > > > > parent object I have to embed parent object into a child. So, I > have > > > > > created the following classes > > > > > > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > > > > > public class Parent { > > > > > @PrimaryKey @Persistent String parentName; > > > > > @Persistent(mappedBy = "parent") List<Child> children = new > > > > > ArrayList<Child>(); > > > > > > > public Parent(String parentName) { this.parentName = parentName; > } > > > > > public void setParentName(String parentName) { this.parentName = > > > > > parentName; } > > > > > public String getParentName() { return parentName; } > > > > > public List<Child> getChildren() { return children; } > > > > > public void addChild(Child child) { > > > > > child.setParent(this); > > > > > children.add(child); > > > > > } > > > > > } > > > > > > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > > > > > public class Child { > > > > > @PrimaryKey > > > > > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) Key > > > > > childKey; > > > > > @Persistent String childName; > > > > > > > @Embedded( > > > > > members = { @Persistent(name = "parentName", column = > > > > > "childParentName") }, > > > > > ownerMember = "children") > > > > > @Persistent Parent parent; > > > > > > > public Child(String childName) { this.childName = childName; } > > > > > public void setChildName(String childName) { this.childName = > > > > > childName; } > > > > > public String getChildName() { return childName; } > > > > > public void setParent(Parent parent) { this.parent = parent; } > > > > > public Parent getParent() { return parent; } > > > > > } > > > > > and then I created a simple test to verify if I can persist and > run > > > > > queries on those objects: > > > > > > > public class ParentTest { > > > > > public static void main(String[] args) { > > > > > Parent parent1 = new Parent("parent1"); > > > > > parent1.addChild(new Child("child1")); > > > > > parent1.addChild(new Child("child2")); > > > > > > > Parent parent2 = new Parent("parent2"); > > > > > parent2.addChild(new Child("child3")); > > > > > > > ApiProxy.setEnvironmentForCurrentThread(new TestEnvironment()); > > > > > ApiProxy.setDelegate(new ApiProxyLocalImpl(new File(".")) { }); > > > > > > > ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) > ApiProxy.getDelegate > > > > > (); > > > > > proxy.setProperty(LocalDatastoreService.NO_STORAGE_PROPERTY, > > > > > Boolean.TRUE.toString()); > > > > > > > PersistenceManagerFactory pmf = > > > > > JDOHelper.getPersistenceManagerFactory("transactions-optional"); > > > > > PersistenceManager pm = pmf.getPersistenceManager(); > > > > > Transaction tx = pm.currentTransaction(); > > > > > try { > > > > > tx.begin(); > > > > > pm.makePersistent(parent1); > > > > > tx.commit(); > > > > > > > tx.begin(); > > > > > pm.makePersistent(parent2); > > > > > tx.commit(); > > > > > > > Query query2 = pm.newQuery(Child.class); > > > > > query2.setFilter("parent.parentName==parentNameParam"); > > > > > query2.declareParameters("java.lang.String parentNameParam"); > > > > > List<Child> results2 = (List<Child>) query2.executeWithArray > > > > > ("parent1"); > > > > > System.err.println(results2); > > > > > } finally { > > > > > if (tx.isActive()) { > > > > > tx.rollback(); > > > > > } > > > > > pm.close(); > > > > > } > > > > > } > > > > > } > > > > > > > The DataNucleus Enhancer runs ok on the above code, but when I > run > > > > > my test app, I am getting an IndexOutOfBoundException from > somewhere > > > > > in the DataNucleus internals: > > > > > > > Exception in thread "main" > java.lang.ArrayIndexOutOfBoundsException: 0 > > > > > at > org.datanucleus.store.appengine.DatastoreTable.initializeNonPK > > > > > (DatastoreTable.java:356) > > > > > at org.datanucleus.store.appengine.DatastoreTable.buildMapping > > > > > (DatastoreTable.java:285) > > > > > at > org.datanucleus.store.appengine.DatastoreManager.buildStoreData > > > > > (DatastoreManager.java:405) > > > > > at org.datanucleus.store.appengine.DatastoreManager.newStoreData > > > > > (DatastoreManager.java:363) > > > > > at org.datanucleus.store.AbstractStoreManager.addClasses > > > > > (AbstractStoreManager.java:788) > > > > > at org.datanucleus.store.AbstractStoreManager.addClass > > > > > (AbstractStoreManager.java:759) > > > > > at > org.datanucleus.store.mapped.MappedStoreManager.getDatastoreClass > > > > > (MappedStoreManager.java:358) > > > > > at > org.datanucleus.store.appengine.DatastoreManager.getDatastoreClass > > > > > (DatastoreManager.java:631) > > > > > at > > > > > > org.datanucleus.store.appengine.DatastoreFieldManager.buildMappingConsumer > > > > > (DatastoreFieldManager.java:1008) > > > > > at > > > > > > org.datanucleus.store.appengine.DatastoreFieldManager.buildMappingConsumer > > > > > (DatastoreFieldManager.java:998) > > > > > at org.datanucleus.store.appengine.DatastoreFieldManager.<init> > > > > > (DatastoreFieldManager.java:133) > > > > > at org.datanucleus.store.appengine.DatastoreFieldManager.<init> > > > > > (DatastoreFieldManager.java:167) > > > > > at > > > > > > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProces > s > > > > > (DatastorePersistenceHandler.java:316) > > > > > at > > > > > > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects > > > > > (DatastorePersistenceHandler.java:236) > > > > > at > > > > > > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject > > > > > (DatastorePersistenceHandler.java:225) > > > > > at > org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent > > > > > (JDOStateManagerImpl.java:3185) > > > > > at org.datanucleus.state.JDOStateManagerImpl.makePersistent > > > > > (JDOStateManagerImpl.java:3161) > > > > > at org.datanucleus.ObjectManagerImpl.persistObjectInternal > > > > > (ObjectManagerImpl.java:1298) > > > > > at org.datanucleus.ObjectManagerImpl.persistObject > > > > > (ObjectManagerImpl.java:1175) > > > > > at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent > > > > > (JDOPersistenceManager.java:669) > > > > > at org.datanucleus.jdo.JDOPersistenceManager.makePersistent > > > > > (JDOPersistenceManager.java:694) > > > > > at org.testgae.ParentTest.main(ParentTest.java:38) > > > > > > > Am I doing something wrong or there is some other way to have > parent- > > > > > child relationship that provides some mechanism include paren'ts > > > > > attributes in query criteria? > > > > > > > Thanks > > > > > > > Eugene > > > > > > > -- > > > > > > > You received this message because you are subscribed to the Google > Groups "Google App Engine for Java" group. > > > > > To post to this group, send email to > google-appengine-j...@googlegroups.com. > > > > > To unsubscribe from this group, send email to > google-appengine-java+unsubscr...@googlegroups.com<google-appengine-java%2bunsubscr...@googlegroups.com> > . > > > > > For more options, visit this group athttp:// > groups.google.com/group/google-appengine-java?hl=en. > > -- > > You received this message because you are subscribed to the Google Groups > "Google App Engine for Java" group. > To post to this group, send email to > google-appengine-j...@googlegroups.com. > To unsubscribe from this group, send email to > google-appengine-java+unsubscr...@googlegroups.com<google-appengine-java%2bunsubscr...@googlegroups.com> > . > For more options, visit this group at > http://groups.google.com/group/google-appengine-java?hl=en. > > > -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-j...@googlegroups.com. To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.