dirkvranckaert dirkvranckaert - 1 month ago 10
Java Question

AppEngine: Cannot read persisted data from datastore in transaction

I'm writing a synchronization service on Google AppEngine but something is not really working for me. What I want to do is to sync an entity Project (maybe it needs to be persisted, maybe just copy the content, who knows), then search for an entity of type Project (might be the same project as persisted first, but doesn't need to be) and then use it to sync a Task.
All of this needs to happen in a transaction so if a task-sync fails that the project is also removed.

I wrote some lines of code to simply test and show what's wrong.
This code works perfectly and shows me "Project Found".

User user = userDao.findAll().get(0);

// Create a setup service...
Project project = new Project();
project.setName("TEST ABC");
project.setLastUpdated(new Date());
project.setUser(user);
projectDao.persist(project);

Project persistedProject = projectDao.find("TEST ABC", user);

if (persistedProject == null) {
System.out.println("Project not found...");
} else {
System.out.println("Project found!");
}


So here I don't use transactions. But when I execute the code with the transactions:

User user = userDao.findAll().get(0);

Transaction tx = datastores.get().beginTransaction();

// Create a setup service...
Project project = new Project();
project.setName("TEST ABC");
project.setLastUpdated(new Date());
project.setUser(user);
projectDao.persist(project);

Project persistedProject = projectDao.find("TEST ABC", user);

if (persistedProject == null) {
System.out.println("Project not found...");
tx.rollback();
} else {
System.out.println("Project found!");
tx.commit();
}


The I always see "Project not found...". So how the hell can i read an object that I have just persisted, but not yet committed?

BTW: I'm using twig-persist 2.0 RC1 and the latest AE SDK (1.7).

So my question is how can I read data that has been persited in the same transaction..?

Answer

You can't. You should re-read the GAE Transaction documentation.

Briefly: everything inside the transaction gets a consistent view of a "snapshot" of what the datastore looks like, so new writes won't show up in queries.

However, you have the project object you persisted, so you should use that instead of querying one.

If you need to do a query, you'll need to manually "join" it with the entities you created within the transaction.