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 [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
-~----------~----~----~----~------~----~------~--~---