views:

92

answers:

2

I see a similar question in Problems while saving a pre-persisted object in Google App Engine (Java), and indeed I was not calling close() on my persistence manager. However, I am now calling close, but my object update is not being persisted. Specifically, I want to remove an element from a Set, and save that smaller set. Here is the persistence manager related code, that doesn't throw an exception, but doesn't save my data:

 UserService userService = UserServiceFactory.getUserService();
 User user = userService.getCurrentUser();

 PersistenceManager pm = PMF.get().getPersistenceManager();
 UserProfileInfo userProfile = pm.getObjectById(UserProfileInfo.class,user.getUserId());
 int presize = userProfile.getAccounts().size();
 AccountInfo ai = userProfile.removeAccount(id);
 int postsize = userProfile.getAccounts().size();
 UserProfileInfo committed = (UserProfileInfo)pm.makePersistent(userProfile);
 int postcommitsize = committed.getAccounts().size();
 pm.close();

And here is the relevant part of the UserProfileInfo class:

@PersistenceCapable(identityType = IdentityType.APPLICATION)
class UserProfileInfo {
  @Persistent
  private Set<AccountInfo> accounts;

public AccountInfo removeAccount(Long id) throws Exception {
 Iterator<AccountInfo> it = accounts.iterator();
 StringBuilder sb = new StringBuilder();
 while(it.hasNext()) {
  AccountInfo acctInfo = it.next();
  Long acctInfoId = acctInfo.getId();
  if(acctInfoId.equals(id)) {
   it.remove();
   return acctInfo;
  }
  sb.append(" ");
  sb.append(acctInfoId);
 }
 throw new Exception("Cannot find id " + id + " Tried " + sb.toString());
  }
}
A: 

I'd have thought that the first thing to do when debugging anything would be to look at the log (DEBUG level). It tells you what states the objects are in at the different points. So what state is it in when you call makePersistent() ? and after ? and what happens when you call pm.close() ...

DataNucleus
For now I just added a 'deleted' field, which I've added to my queries. I did see a hint when working with another class - that the primary key of an owned object cannot be a 'Long' I'm not sure why that warning wasn't shown for my AccountInfo object, since it is using Long as the primary key, and it is owned. I'll try changing it to String, and see how that goes.
Michael Donohue
+1  A: 

So it looks like the answer is owned objects cannot use a Long primary key. The datanucleus enhancer told me this for another object type I added. I'm not sure why it skipped this warning for my AccountInfo object.

I switched my key over to a String, and changed the annotations to use the string properly, and now I'm able to delete from the collection.

Michael Donohue