After some more testing this is what I observe: - If A has one C property and B has two C properties, I can save both the A and the B instances, when I get the B instance, both C properties point to the same instance of C. - If A has one C property and B has a property that is a List of Cs, I get the exception in my original post.
I guess I need to work this down to a repeatable example and file a defect report. On Sep 21, 2:49 pm, objectuser <[email protected]> wrote: > I'll let leszek talk more about the code, but I assumed that the > commented out line was just testing both scenarios. In the scenario > without comment on the line, it would be my scenario: the same "owned > type" but not the same "owned instance". > > My original question is not about one particular entity having two > parents (in an owned relationship), but having two entity groups share > the same "owned" Java type. > > Does that make sense? > > On Sep 21, 2:00 pm, Marton Papp <[email protected]> wrote: > > > Hi, > > > The code in that form also works for me, but just because the > > exception is caught and never reported. If you rethrow any exceptions > > from the catch blocks than you should get something like the > > following: > > > Detected attempt to establish Parent2(3) as the parent of Parent1(1)/ > > Child1(2) but the entity identified by Parent1(1)/Child1(2) is already > > a child of Parent1(1). A parent cannot be established or changed once > > an object has been persisted. > > org.datanucleus.exceptions.NucleusUserException: Detected attempt to > > establish Parent2(3) as the parent of Parent1(1)/Child1(2) but the > > entity identified by Parent1(1)/Child1(2) is already a child of Parent1 > > (1). A parent cannot be established or changed once an object has > > been persisted. > > at > > org.datanucleus.store.appengine.DatastoreRelationFieldManager.checkForParentSwitch > > (DatastoreRelationFieldManager.java:214) > > 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:795) > > 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 hu.mapro.gae.test.forum.TestForum.testMultiParent(TestForum.java: > > 44) > > 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:597) > > at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) > > at org.junit.internal.runners.MethodRoadie.runTestMethod > > (MethodRoadie.java:98) > > at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java: > > 79) > > at > > org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters > > (MethodRoadie.java:87) > > at > > org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java: > > 77) > > at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42) > > at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod > > (JUnit4ClassRunner.java:88) > > at org.junit.internal.runners.JUnit4ClassRunner.runMethods > > (JUnit4ClassRunner.java:51) > > at org.junit.internal.runners.JUnit4ClassRunner$1.run > > (JUnit4ClassRunner.java:44) > > at org.junit.internal.runners.ClassRoadie.runUnprotected > > (ClassRoadie.java:27) > > at org.junit.internal.runners.ClassRoadie.runProtected > > (ClassRoadie.java:37) > > at org.junit.internal.runners.JUnit4ClassRunner.run > > (JUnit4ClassRunner.java:42) > > at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run > > (JUnit4TestReference.java:46) > > at org.eclipse.jdt.internal.junit.runner.TestExecution.run > > (TestExecution.java:38) > > at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests > > (RemoteTestRunner.java:467) > > at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests > > (RemoteTestRunner.java:683) > > at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run > > (RemoteTestRunner.java:390) > > at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main > > (RemoteTestRunner.java:197) > > > The error message is self-explanatory. According to my knowledge it is > > impossible for a single entity to have multiple parents, just as it is > > impossible to change the parent of an entity (or any other part of its > > primary key). > > > But you were talking about a "class" being in owned realationship with > > two different classes, not an "entity". If I remove the comment from > > the code above that creates a new child entity before assigning it to > > the second parent instance then it is working as expected. Of course > > they will be two different employee instances with different parents > > (of different types). > > > Marton > > > On Sep 21, 4:49 pm, leszek <[email protected]> wrote: > > > > That's very interesting because it works for me: > > > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > > > public class Employee { > > > > @PrimaryKey > > > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > > > private Key id; > > > > private String firstName; > > > > private String lastName; > > > > } > > > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > > > public class A (B) { > > > > public Long getId() { > > > return id; > > > } > > > > public void setId(Long id) { > > > this.id = id; > > > } > > > > public Employee getE() { > > > return e; > > > } > > > > public void setE(Employee e) { > > > this.e = e; > > > } > > > > @PrimaryKey > > > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > > > private Long id; > > > > } > > > > ======================== > > > (regardless if transaction is used or not - simply makePersistent > > > without transaction) > > > > PersistenceManager em = EMF.get().getPersistenceManager(); > > > Employee e = null; > > > try { > > > em.currentTransaction().begin(); > > > A a = new A(); > > > e = new Employee(); > > > a.setE(e); > > > em.makePersistent(a); > > > em.currentTransaction().commit(); > > > } catch (Exception ee) { > > > em.currentTransaction().rollback(); > > > } > > > > try { > > > em.currentTransaction().begin(); > > > B b = new B(); > > > // e = new Employee(); > > > b.setE(e); > > > em.makePersistent(b); > > > em.currentTransaction().commit(); > > > } catch (Exception ee) { > > > em.currentTransaction().rollback(); > > > } --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
