Hi there, I am trying to handle some really simple Relationships with JDO and Datanucleus.
I read one thread about a similar Problem. But the developer in that thread handles the keys by himself. He generates the keys with a KeyFactory and stores just Keys instead of the dependent Object. Do I have to code my own Persistence-Layer for GAE, which handles Associations? That cannot be the way to do that. My model looks like that: User <----- MobilePhone -----> Model ----> Series The MobilePhone has an owner and a creator, each identified by an User. The MobilePhone has a Model attached which has a Series attached. An User can be owner and creator of many MobilePhones; a MobilePhone needs a creator, but not necessarily an owner. A Model can be attached to many MobilePhones, a MobilePhone needs a Model (not null). A Series can be attached to many Models, a Model needs a Series (not null). My classes look like (shorted): @PersistenceCapable(identityType = IdentityType.APPLICATION) public class Series implements IsSerializable { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private String term; (..) } @PersistenceCapable(identityType = IdentityType.APPLICATION) public class Model implements IsSerializable { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private String name; @Persistent private Series series; (..) } @PersistenceCapable(identityType = IdentityType.APPLICATION) public class MobilePhone implements IsSerializable { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private String description; @Persistent(dependent = "false") private User owner; @Persistent(dependent = "false") private User creator; @Persistent(dependent = "false") private Model model; (..) } @PersistenceCapable(identityType = IdentityType.APPLICATION) public class User { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private String firstname; @Persistent private String familyname; (..) } In my test I create two Users (creator and owner). @Before public void setup() throws Exception { this.pm = EMF.get().getPersistenceManager(); this.owner = new User(); this.owner.setFamilyname("h"); this.owner.setFirstname("b"); this.owner = this.pm.makePersistent(this.owner); this.creator = new User(); this.creator.setFamilyname("h"); this.creator.setFirstname("b"); this.creator = this.pm.makePersistent(this.creator); this.assertTable(2, User.class); } @Test public void createHandy() throws Exception { Series ht = new Series(); ht.setTerm("I"); Model hm = new Model(); hm.setName("name"); hm.setSeries(ht); MobilePhone h = new MobilePhone(); h.setCreator(this.creator); h.setDescription("b"); h.setModel(hm); h.setOwner(this.owner); this.pm.makePersistent(h); this.assertTable(1, HandyTypeSeries.class); this.assertTable(1, HandyModel.class); this.assertTable(1, Handy.class); } This works fine. But when I try to persist a MobilePhone with the attached Users, I get the following Exception. javax.jdo.JDOFatalUserException: Detected attempt to establish Handy (3) as the parent of User(1) but the entity identified by User(1) has already been persisted without a parent. A parent cannot be established or changed once an object has been persisted. at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException (NucleusJDOHelper.java:406) at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent (JDOPersistenceManager.java:673) at org.datanucleus.jdo.JDOPersistenceManager.makePersistent (JDOPersistenceManager.java:693) at de.keineantwort.MobilePhonerater.gwt.server.MobilePhone.MobilePhonePersistenceTest.createMobilePhone (MobilePhonePersistenceTest.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.junit.internal.runners.TestMethodRunner.executeMethodBody (TestMethodRunner.java:99) at org.junit.internal.runners.TestMethodRunner.runUnprotected (TestMethodRunner.java:81) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected (BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestMethodRunner.runMethod (TestMethodRunner.java:75) at org.junit.internal.runners.TestMethodRunner.run (TestMethodRunner.java:45) at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod (TestClassMethodsRunner.java:66) at org.junit.internal.runners.TestClassMethodsRunner.run (TestClassMethodsRunner.java:35) at org.junit.internal.runners.TestClassRunner$1.runUnprotected (TestClassRunner.java:42) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected (BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestClassRunner.run (TestClassRunner.java:52) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:45) at org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:196) NestedThrowablesStackTrace: Detected attempt to establish MobilePhone(3) as the parent of User(1) but the entity identified by User(1) has already been persisted without a parent. A parent cannot be established or changed once an object has been persisted. org.datanucleus.exceptions.NucleusUserException: Detected attempt to establish MobilePhone(3) as the parent of User(1) but the entity identified by User(1) 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:206) at org.datanucleus.store.appengine.DatastoreRelationFieldManager $1.setObjectViaMapping(DatastoreRelationFieldManager.java:129) at org.datanucleus.store.appengine.DatastoreRelationFieldManager $1.apply(DatastoreRelationFieldManager.java:108) at org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations (DatastoreRelationFieldManager.java:80) at org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations (DatastoreFieldManager.java:770) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject (DatastorePersistenceHandler.java:231) at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent (JDOStateManagerImpl.java:3067) at org.datanucleus.state.JDOStateManagerImpl.makePersistent (JDOStateManagerImpl.java:3043) at org.datanucleus.ObjectManagerImpl.persistObjectInternal (ObjectManagerImpl.java:1258) at org.datanucleus.ObjectManagerImpl.persistObject (ObjectManagerImpl.java:1135) at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent (JDOPersistenceManager.java:668) at org.datanucleus.jdo.JDOPersistenceManager.makePersistent (JDOPersistenceManager.java:693) at de.keineantwort.MobilePhonerater.gwt.server.MobilePhone.MobilePhonePersistenceTest.createMobilePhone (MobilePhonePersistenceTest.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.junit.internal.runners.TestMethodRunner.executeMethodBody (TestMethodRunner.java:99) at org.junit.internal.runners.TestMethodRunner.runUnprotected (TestMethodRunner.java:81) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected (BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestMethodRunner.runMethod (TestMethodRunner.java:75) at org.junit.internal.runners.TestMethodRunner.run (TestMethodRunner.java:45) at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod (TestClassMethodsRunner.java:66) at org.junit.internal.runners.TestClassMethodsRunner.run (TestClassMethodsRunner.java:35) at org.junit.internal.runners.TestClassRunner$1.runUnprotected (TestClassRunner.java:42) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected (BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestClassRunner.run (TestClassRunner.java:52) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:45) at org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:196) --~--~---------~--~----~------------~-------~--~----~ 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-java@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 -~----------~----~----~----~------~----~------~--~---