Java – updating an object with JDO and GAE

google-app-enginejavajdo

So, I'm creating a small web app using Wicket that will run on the google app engine. I'm using JDO, and so far have no problems persisting data (inserts) or querying data those same data objects. Maybe I'm missing some basic thing, I'm trying to take one of those persisted objects, change two values and then I want that modified object to be updated in the datastore.

I have a User object thats persisted. I can query this so I know the object itself has correct annotations.

The code I'm running to update it is:

final PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction trans = pm.currentTransaction();
try{ 
  trans.begin();
  user.setLoginCount(user.getLoginCount()+1);
  user.setLastLoginTime(new Date());
  trans.commit();
}finally{
  if (trans.isActive()) {
    trans.rollback();
    System.out.println("----transaction rollback - submitLogin----");
  }
  pm.close();
}

Here's my User objects annotations for those two things I want to change…

@Persistent
private Date lastLoginTime;

@Persistent
private int loginCount = 0;

I do a query right after this code and it returns the same object before I changed values.
Any ideas what I'm doing wrong?

Best Answer

By default, JDO objects are only valid when the PersistenceManager that created them is open. You say you have already called makePersistent() on the user object. That means you had another PersistenceManager open before the one you show us in the code above. When you closed that PersistenceManager (presumably you closed it), your object became invalid,(informally speaking.)

Depending on what you want to do, you have two options.

  1. You can detach your user object, which will allow it to have a life outside the context of it's original persistence manager.

  2. You can get a fresh copy of the object using the new PersistenceManager you just created

here is some code for option #2:

trans.begin();
User user = (User) pm.getObjectById(User.class,"userkeyhere");
user.setLoginCount(user.getLoginCount()+1);
user.setLastLoginTime(new Date());
trans.commit();