You can not retrieve Child Object directly via Id with JDO.

GAE datastore keep a unique
key<http://code.google.com/appengine/docs/java/datastore/creatinggettinganddeletingdata.html#Keys>for
every storage object. For root object the key should be like
ObjectClassSimpleName#1 , while for child object the key would be
ParentObjectClassSimpleName#1/ChildObjectClassSimpleName#2 . (#1 and #2 is
the Id of the Object)

When using JDO getObjectById, as my understanding, GAE will create a key (by
the class kind and id you passed), and retrieve the Object via this key. So
your code will be equal to:
Child child= pm.getObjectById(Child.class, childId);
=>
Key childKey = KeyFactory.createKey(Child.class.getSimpleName(), childId);
// retrieve Entity via childKey, and convert it to Child Object

Above code will not work, as the real key of the child should be created via
this:
Key parentKey = KeyFactory.createKey(Parent.class, parentId);
Key realChildKey = KeyFactory.createKey(parentKey, Child.class, childId);
// retrieve Entity via realChildKey, and convert it to Child Object

So, if decided to use
owned-relationship<http://code.google.com/appengine/docs/java/datastore/relationships.html>,
child object should be get by it's parent key combined with child key. Other
two solution for this issue:
1. Don't use owned-relationship, use Key reference instead. See
unowned-relationship<http://code.google.com/appengine/docs/java/datastore/relationships.html#Unowned_Relationships>
.
2. Query the child object by user defined property instead of Key or Id(
Id/Name is not key exactly).

I have been annoyed by this problem, too. It seems not a good idea to use
owned-relationship every place, but owned-relationship is high performance
than unowned-relationship. So there is a balance we should consider.


On Tue, Mar 30, 2010 at 4:56 PM, Emmanuel <[email protected]>wrote:

> Hi,
>
> I'm fairly new to JDO and App Engine and actually facing an odd
> problem.
> I'm trying to retrieve a child object with the method
> pm.getObjectById(Child.class, Id) but this method throws me a
> JDOObjectNotFoundException. I'm sure that the child object exists and
> in facts, when I retrieve the parent object with the same method
> before calling it for the child object, everything works fine.
> It seems like I'm missing something so here is my code :
>
> @PersistenceCapable(identityType = IdentityType.APPLICATION)
> public class Parent{
>
>        @PrimaryKey
>        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
>        private Key key;
>
>        @Persistent
>        private String title;
>
>        @Persistent(mappedBy="parent", defaultFetchGroup="true")
>        private List<Child> childs;
>
>
>        public Parent(String title, List<Child> childs) {
>                super();
>                this.title = title;
>                this.childs = childs;
>                this.configuration = configuration;
>                this.utilisateur = utilisateur;
>                this.commentaires = commentaires;
>        }
> }
>
>
>
> @PersistenceCapable(identityType = IdentityType.APPLICATION)
> public class Child{
>
>        @PrimaryKey
>        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
>        private Key key;
>
>        @Persistent
>        private Parent parent;
>
>        @Persistent
>        private String title;
>
>        @Persistent
>        private String content;
>
>
>
>        public Bloc(String title, String content) {
>                super();
>                this.title = title;
>                this.content = content;
>        }
>
> }
>
> And my code for getting the object :
>
> PersistenceManager pm = PMF.get().getPersistenceManager();
> Transaction tx = pm.currentTransaction();
> try{
>        tx.begin();
>        // If I add a line here : Parent parent =
> pm.getObjectById(Parent.class, parentId); the code works.
>        Child child= pm.getObjectById(Child.class, childId); // childId is a
> long
>
>       //Code making changes to child object but it doesn't get that
> far...
>
>        tx.commit();
> }
> finally{
>        if(tx.isActive())
>        tx.rollback();
> }
> pm.close();
>
> So here is my problem. Hope someone can help me ^^.
>
> --
> 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
> [email protected].
> To unsubscribe from this group, send email to
> [email protected]<google-appengine-java%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-appengine-java?hl=en.
>
>


-- 
Best Regards,
>From Raymond Ling

-- 
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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to