dipaksavaliya / datanucleus-appengine

Automatically exported from code.google.com/p/datanucleus-appengine
0 stars 0 forks source link

Detect objects that are owned by multiple types #170

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
A type can only have a single owner, so this should be illegal:

  @PersistenceCapable(identityType = IdentityType.APPLICATION)
  public static class RatePlan {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key id;
  }

  @PersistenceCapable(identityType = IdentityType.APPLICATION)
  public static class Activity {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key id;

    @Persistent
    private List<RatePlan> ratePlans = new ArrayList<RatePlan>();
  }

  @PersistenceCapable(identityType = IdentityType.APPLICATION)
  public static class Bundle {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key id;

    @Persistent
    private RatePlan ratePlan;

    public void setRatePlan(RatePlan ratePlan) {
      this.ratePlan = ratePlan;
    }
  }

Right now we throw a really cryptic exception:
  public void testBryce() {
    switchDatasource(PersistenceManagerFactoryName.nontransactional);

    pm.newQuery(Activity.class).execute();

    Bundle bundle = new Bundle();
    bundle.setRatePlan(new RatePlan());

    pm.makePersistent(bundle);
  }

java.lang.ClassCastException: oid is not instanceof 
javax.jdo.identity.ObjectIdentity
    at 
org.datanucleus.test.Bryce$RatePlan.jdoCopyKeyFieldsFromObjectId(Bryce.j
ava)
    at 
org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObj
ectAsValue(PersistenceCapableMapping.java:657)
    at 
org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObj
ect(PersistenceCapableMapping.java:364)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.setObje
ctViaMapping(DatastoreRelationFieldManager.java:131)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(D
atastoreRelationFieldManager.java:107)
    at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelat
ions(DatastoreRelationFieldManager.java:79)
    at 
org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(Dat
astoreFieldManager.java:812)
    at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostPr
ocess(DatastorePersistenceHandler.java:288)
    at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject
s(DatastorePersistenceHandler.java:241)
    at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(
DatastorePersistenceHandler.java:225)
    at 
org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStat
eManagerImpl.java:3185)
    at 
org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManag
erImpl.java:3161)
    at 
org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerI
mpl.java:1298)
    at 
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:
1175)
    at 
org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersiste
nceManager.java:669)
    at 
org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistence
Manager.java:694)

Original issue reported on code.google.com by max.r...@gmail.com on 9 Dec 2009 at 2:20

GoogleCodeExporter commented 8 years ago
Forgot to say that the fix is to throw a useful exception.

Original comment by max.r...@gmail.com on 9 Dec 2009 at 2:20

GoogleCodeExporter commented 8 years ago
What's the status on this? I think I have a problem that is related to this bug 
(and took me a while to figure out because of the weird exception too).

If I run:
    @Test
    public void testABC() throws TransactionFailed
    {
        C c = new C();

        final A a = new A();

        B b = new B();
        b.myC = c;

        a.bList.add(b);

        pm.makePersistent(a);
    }

With the following data model:
    public class A {

        @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        private Key key;

        @Persistent(mappedBy = "myA")
        @Element(dependent = "true")
        public LinkedList<B> bList = new LinkedList<B>();

        @Persistent
        @Element(dependent = "true")
        public LinkedList<C> cList = new LinkedList<C>();
    }

    @PersistenceCapable(identityType = IdentityType.APPLICATION)
    public class B {

        @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        private Key key;

        /**
         * This is automatically set to the user this post
         * is added to (when that user is made persistent).
         */
        @Persistent
        private A myA;

        @Persistent
        public C myC;
    }

    @PersistenceCapable(identityType = IdentityType.APPLICATION)
    public class C {

        @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        private Key key;
    }

I also obtain:
java.lang.ClassCastException: oid is not instanceof 
javax.jdo.identity.ObjectIdentity

The WEIRD thing is: if in class A I change cList from using a LinkedList to a 
HashSet it doesn't break anymore (this simplified data model is part of a much 
bigger test suite and when using a HashSet all the tests pass, when using a 
LinkedList some of them break (i.e. all of those actually populating bList))

Should I file this as a separate issue? This bug is the closest thing I could 
find related to my issue.

I understand that apparently it is not possible for C, as a child, to have more 
than one parent type it seems. I understand why this is true for a given C 
object, but why can't another C object be owned by a different parent type (in 
my case C is a multi purpose object, and it would just lame to need a different 
type of C for each class that could need a version of it (although each 
potential parent has it's own C's, none are actually shared among parents...)) 

Thanks,
Gabriel

Original comment by gcharet...@gmail.com on 18 Jul 2011 at 5:08

GoogleCodeExporter commented 8 years ago

Original comment by googleco...@yahoo.co.uk on 17 Apr 2012 at 9:08