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.
Alternatively, Twig makes embedding objects very simple.  If you use
the AnnotationTypesafeDatastore you can achieve the above with a
single annotation:

@Component
Parent parent;

However, currently Twig does not support the parent being _both_ an
embedded "component" and an "entity".  It must be one of the other.
It will support this type of denormalisation in the next release which
I hope to get out a week or so after new year.

http://code.google.com/p/twig-persist/

John

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.
> > > 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.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.


Reply via email to