Has anyone figured out a convention for this? Rusty I like your idea of populating the Race in the Result entity but re-attaching the object later would cause problems (would you have to set Race to null before persisting again?). I too find it odd to have entity object performing queries but if that is the best way then I guess I'll have to just do it. Hopefully someone at Google could comment on this.
On Feb 8, 12:17 pm, Rusty Wright <[email protected]> wrote: > I agree with Jake; relationships are tricky. Likewise with his pointing out > that having race be in two Results will be a problem; that won't fly. > > Another way would be to have a List<Result> in Race, and add your Results to > that. But you're still going to have parenting problems when you have the > same runner in different races; that's where I'd store the Runner's Key in > the Result. > > Having the Result query the datastore seems odd to me; I was thinking of > doing that but it seems to me that these persistent objects ought to be > fairly simple data transfer objects and shouldn't be doing that. The DAO > does the datastore interactions. If you were doing the fully layered way, > with domain objects (that is, these data transfer objects), DAOs, and a > service layer, I could see the service layer calling the DAOs, and then it > calls the setters on the domain objects to fill in the missing stuff, like > the Race in the Result here. But that seems "dirty" to me; shouldn't the ORM > be doing this for us? > > > > > > Jake wrote: > > Hey, > > > Relationships in GAE are a bit picky. It is my understanding that you > > can only persist children by way of persisting their parents. So, in > > your case, both Race and Runner are children of Result and you would > > only persist the two result objects - the dependent children would be > > persisted automatically. I'm willing to bet, though, that a single > > race object cannot be the child of two different parent objects, > > though I'm not certain. The details are all here: > >http://code.google.com/appengine/docs/java/datastore/relationships.html > > > For the most part, I've found that parent/child relationships are only > > useful when the two are highly related - usually when I'm extending a > > class to provide more data. (e.g. Race -> RaceDetails). > > > The "easy" way to get around this is to store the objects in unowned > > relationships, referencing other objects by IDs as described in > >http://code.google.com/appengine/docs/java/datastore/relationships.ht.... > > Then, with some fancy getters/setters that automatically query the > > Datastore, you end up with the same result. See my example below. > > > If anyone has any other advice, though, please contribute. I haven't > > found a great way to handle this and I'm trying to avoid using GAE > > specific libraries to help. > > > Jake > > > public class Race { > > > private Key id; > > ... > > } > > > public class Result { > > > private Key id; > > private Key raceId; > > > public Race getRace() { > > //query datastore with getObjectById(Race.class, raceId); > > } > > } > > > On Feb 6, 7:15 pm, Rodolphe <[email protected]> wrote: > >> Hello, > > >> I am very new to appengine, and I am trying a very basic model exemple: A > >> Race class is linked to a Runner class through a Result class > > >> When I am running the folloging code (the full code is attached): > >> Race race = new Race("Paris", new Date(), 10); > > >> Runner runner1 = new Runner("Smith"); > >> Runner runner2 = new Runner("John"); > > >> Result result1 = new Result(race, runner1, 1); > >> Result result2 = new Result(race, runner2, 2); > > >> PersistenceManager pm = PMF.get().getPersistenceManager(); > >> try { > >> race = pm.makePersistent(race); > > >> runner1 = pm.makePersistent(runner1); > >> runner2 = pm.makePersistent(runner2); > > >> pm.makePersistent(result1); > >> pm.makePersistent(result2); > >> } finally { > >> pm.close(); > >> } > > >> I get the following error: > >> Detected attempt to establish Result(4) as the parent of Runner(2) but the > >> entity identified by Runner(2) has already been persisted without a parent. > >> A parent cannot be established or changed once an object has been > >> persisted. > >> org.datanucleus.store.appengine.FatalNucleusUserException: Detected attempt > >> to establish Result(4) as the parent of Runner(2) but the entity identified > >> by Runner(2) has already been persisted without a parent. A parent cannot > >> be established or changed once an object has been persisted. > >> at > >> org.datanucleus.store.appengine.DatastoreRelationFieldManager.checkForParen > >> tSwitch(DatastoreRelationFieldManager.java:204) > >> at > >> org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.setObjectVi > >> aMapping(DatastoreRelationFieldManager.java:125) > >> at > >> org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(Datas > >> toreRelationFieldManager.java:104) > >> at > >> org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelation > >> s(DatastoreRelationFieldManager.java:78) > >> at > >> org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(Datast > >> oreFieldManager.java:812) > >> at > >> org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProce > >> ss(DatastorePersistenceHandler.java:288) > >> at > >> org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(D > >> atastorePersistenceHandler.java:241) > >> at > >> org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(Da > >> tastorePersistenceHandler.java:225) > >> at > >> org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateMa > >> nagerImpl.java:3185) > >> at > >> org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImp > >> l.java:3161) > >> at > >> org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.j > >> ava:1298) > >> at > >> org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175 > >> ) > >> at > >> org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceM > >> anager.java:669) > >> at > >> org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceMana > >> ger.java:694) > >> at race.TestRace.test2(TestRace.java:58) > > >> Any idea how I could solve this ? > > >> Thank you in advance > >> Rodolphe > > >> TestRace.java > >> 3KViewDownload > > >> Race.java > >> 1KViewDownload > > >> Result.java > >> 1KViewDownload > > >> Runner.java > >> 1KViewDownload > > -- > 0x2B | ~0x2b -- Hamlet -- 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.
