MountainClimb / datanucleus-appengine

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

Child objects with gae.pk-id cannot be updated due to org.datanucleus.store.appengine.FatalNucleusUserException: Attempt was made to modify the primary key #222

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create a child object with a:
    @Persistent
    @Extension(vendorName="datanucleus", key="gae.pk-id", value="true")
    private Long keyId;

2. Server side query and detach it, return it via RPC to GWT (or anything)
return pm.detachCopy(foo);

3. Manipulate it in GWT and then RPC it back and save it:
PersistenceManager pm = PMF.get().getPersistenceManager();

        try {
            return pm.detachCopy(pm.makePersistent(settings));
        } finally {
            pm.close();
        }

What is the expected output? What do you see instead?

Expect it to save. Instead it causes this exception (from 
DatastoreFieldManager):

  throw new FatalNucleusUserException(
              "Attempt was made to modify the primary key of an object of type "
              + getStateManager().getClassMetaData().getFullClassName() + " identified by "
              + "key " + datastoreEntity.getKey() + "  Primary keys are immutable.  "
              + "(New value: " + key);

In my case it is missing the parent in the key:

Attempt was made to modify the primary key of an object of type 
com.x.shared.entity.XSettings identified by key 
DataSourceSettings(1)/XSettings(2)  Primary keys are immutable.  (New value: 
XSettings(2)

What version of the product are you using? On what operating system?
Mac OSX, 
Your SDK: Release: 1.3.7

Please provide any additional information below.

It looks like this method in DatastoreFieldManager ~ line 478:

void storePKIdField(int fieldNumber, Object value) {
    if (!fieldIsOfTypeLong(fieldNumber)) {
      throw new FatalNucleusUserException(
          "Field with \"" + DatastoreManager.PK_ID + "\" extension must be of type Long");
    }
    Key key = null;
    if (value != null) {
      key = KeyFactory.createKey(datastoreEntity.getKind(), (Long) value);
    }
    storeKeyPK(key);
    pkIdPos = fieldNumber;
  }

Should check for a parent and if one exists, use the parent when generating the 
key?

Original issue reported on code.google.com by ashley.s...@gmail.com on 22 Sep 2010 at 1:44

GoogleCodeExporter commented 8 years ago
Can't reproduce. Please provide a complete testcase (model class, persistence 
code, etc)

Original comment by googleco...@yahoo.co.uk on 29 Sep 2011 at 1:16

GoogleCodeExporter commented 8 years ago
No testcase was provided so marking Invalid.

Original comment by max.r...@gmail.com on 20 Jan 2012 at 8:53