开发者

Updating child objects in Google App Engine using DataNucleus JDO

开发者 https://www.devze.com 2023-02-10 10:25 出处:网络
I have spent several hours trying to work this one out and I just can\'t seem to get my child entities to update despite trying several suggestions.I have looked at the GAE documents extensively and I

I have spent several hours trying to work this one out and I just can't seem to get my child entities to update despite trying several suggestions. I have looked at the GAE documents extensively and I have tried placing things in transactions, tried making them "owned" objects and making them part of the "default fetch group." The objects are correctly persisted in the datastore after running the dummy "populateDatastore" method below and I can retrieve them from the datastore with no issue. When I make changes, those changes are not persisted, although I am using the setter methods so JDO picks up the changes. I am not a Java expert, so I may be doing something really obviously wrong and I don't see it.

Parent object

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Parent {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent
  private String invitationCode;

  @Persistent(defaultFetchGroup = "true")
  private Child child;

  // additional ivars and getters and setters
}

Child object

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Response {

  @Prima开发者_运维知识库ryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent(mappedBy = "child")
  private Parent parent;

  // additional ivars and getters and setters
}

I have several methods to retrieve and save objects.

public void persistParent(Parent p, boolean closeSession){
  manager = PMF.get().getPersistenceManager();
  manager.makePersistent(p);

  if(closeSession) {
    manager.close();
  }
}

public Transaction beginTransaction() {
  int retries = 3;
  manager = PMF.get().getPersistenceManager();
  Transaction tx = manager.currentTransaction();

  try {
    tx.begin();
  }
  catch(com.google.apphosting.api.ApiProxy.CapabilityDisabledException e) {
    return null;
  }
  catch(Exception e) {
    return null;
  }
  return tx;
}

public boolean endTransaction(Transaction tx) throws Exception {
  int retries = 3;
  try {
    tx.commit();
  }
  catch(ConcurrentModificationException e) {
if (retries == 0) {
      throw e;
    }
--retries;
  }
  catch(com.google.apphosting.api.ApiProxy.CapabilityDisabledException e) {
    if (retries == 0) {
      throw e;
    }
--retries;
  }
  catch(Exception e) {
    if (retries == 0) {
      throw e;
    }
    --retries;
  }
  finally {
    if(tx.isActive()) {
      tx.rollback();
    }
  }

  manager.close();

  return true;
}

public List<Parent> getParentWithID(String code, boolean closeSession) {
  Query q = PMF.get().getPersistenceManager().newQuery(Parent.class);
  q.setFilter("code == codeParam");
  q.declareParameters("String invitationCodeParam");

  List<Invitation> results = null;
  try {
    results = (List<Parent>) q.execute(code);
  } 
  finally {
    if(closeSession) {
      q.closeAll();
    }
  }

 return results;
 }

Lastly, I have a dummy method to throw some data into the datastore for testing. I add several children to the children list but for brevity's sake, I have cut out a lot of the redundant code. I also persist several parent objects as well.

Child c = new Child(arg1, arg2, arg3);
c.setSomeIVarForChild(arg1);
p = new Parent(arg1, arg2, arg3);
p.getChildList().add(c);
rsvpDao.persistParent(p, true);


I don't know exactly what is the implementation behind "PMF.get()", but in case you are creating a new PersistenceManagerFactory on each get() - there is no need, you can just hold it as a static member. If this is not the problem, try checking if you are using the same PersistenceManager for retrieving and updating the data objects: meaning only one call to PMF.get().getPersistenceManager() for the entire operation. In case you need to query for objects and then persist them later using a different PersistenceManager, you should detach


Problem which I faced was my parent object primary key was "Key" object. Changing to to Long worked. Not sure what is the exact issue and how it solved the problem as I'm new to android and gae


I've added the following and it fixed my issue:

if(JDOHelper.getPersistenceManager(obj) != pm) {
    logger.error("JDOHelper.getPersistenceManager(obj) != pm  ->     JDOHelper.getPersistenceManager(obj)[" +     JDOHelper.getPersistenceManager(obj).toString() + "]"
                            + " pm[" + pm.toString() + "]");
                    detatchedJob =     JDOHelper.getPersistenceManager(obj).detachCopy(obj);
                    jobs.add(detatchedJob);
                } else {
                    detatchedJob = pm.detachCopy(obj);
                    jobs.add(detatchedJob);
                }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号