I am trying to persist Java objects to the GAE datastore.
I am not sure as to how to persist object having (“non-trivial”) referenced object.
That is, assume I have the following.
public class Father {
String name;
int age;
Vector<Child> offsprings; //this is what I call "non-trivial" reference
//ctor, getters, setters...
}
public class Child {
String name;
int age;
Father father; //this is what I call "non-trivial" reference
//ctor, getters, setters...
}
The name field is unique in each type domain, and is considered a Primary-Key.
In order to persist the “trivial” (String, int) fields, all I need is to add the correct annotation. So far so good.
However, I don’t understand how should I persist the home-brewed (Child, Father) types referenced.
Should I:
- Convert each such reference to hold the Primary-Key (a name String, in this example) instead of the “actual” object, so
Vector<Child> offsprings;becomesVector<String> offspringsNames;?If that is the case, how do I handle the object at run-time? Do I just query for the Primary-Key from
Class.getName, to retrieve the refrenced objects? - Convert each such reference to hold the actual Key provided to me by the Datastore upon the proper
put()operation? That is,Vector<Child> offsprings;becomesVector<Key> offspringsHashKeys;?
I have read all the offical relevant GAE docs/example. Throughout, they always persist “trivial” references, natively supported by the Datastore (e.g. in the Guestbook example, only Strings, and Longs).
Please see google appengine docs following sections for more clear understanding (Relationships, Transactions)
Also read about detachable objects in JDO
For your question You have several options:
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true") public class Father { @PrimaryKey @Persistent private String name; @Persistent private int age; @Persistent(mappedBy = "father", defaultFetchGroup = "false") private List childern; } @PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true") public class Child { @Persistent @PrimaryKey private String name; @Persistent private Father dad; }@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true") public class Father { @PrimaryKey @Persistent private String name; @Persistent private int age; @Persistent private List childern; } @PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true") public class Child { @Persistent @PrimaryKey private String name; @Persistent private Key dad; }In this case you will have to manage the referential integrity and also make sure they are in the same entity group if you have to update/add them in a single transaction
IMO, if I were modeling a real-world (Father-children) scenario, I’d go the “Owned relatinship” route, since, really, how many children a guy can have ;). Of course there is an additional question of how many fathers are you going to update at a time?
Hope this helps, cheers!