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

Reply via email to