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

Reply via email to