[appengine-java] Re: JDO model issue
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 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 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 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 > >>
Re: [appengine-java] Re: JDO model issue
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 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.html#Unowned_Relationships. 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 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.checkForParentSwitch(DatastoreRelationFieldManager.java:204) at org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.setObjectViaMapping(DatastoreRelationFieldManager.java:125) at org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(DatastoreRelationFieldManager.java:104) at org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations(DatastoreRelationFieldManager.java:78) at org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(DatastoreFieldManager.java:812) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProcess(DatastorePersistenceHandler.java:288) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:241) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:225) at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185)
[appengine-java] Re: JDO model issue
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.html#Unowned_Relationships. 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 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.checkForParentSwitch(DatastoreRelationFieldManager.java:204) > at > org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.setObjectViaMapping(DatastoreRelationFieldManager.java:125) > at > org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(DatastoreRelationFieldManager.java:104) > at > org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations(DatastoreRelationFieldManager.java:78) > at > org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(DatastoreFieldManager.java:812) > at > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProcess(DatastorePersistenceHandler.java:288) > at > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:241) > 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 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 -- 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...@googleg