My servlet should perform the following : when a user registers at a venue, I check whether he's currently registered somewhere (even if it is the same venue) if so, unregister him and to register him once again.
I have the following code, which I've simplified in order to show my problem :
Date tempDate = new Date();
Visit v = ofy().load().type(Visit.class)
.filter(Visit.USER_ID, 5L)
.filter(Visit.EXIT_DATE, null).first().get();
if(v != null)
exitVenue(5L, 7L, tempDate);
Visit visit = new Visit(5L, 7L, tempDate);
ofy().save().entity(visit).now();
Date tempDate2 = new Date();
Visit v2 = ofy().load().type(Visit.class)
.filter(Visit.USER_ID, 5L)
.filter(Visit.EXIT_DATE, null).first().get();
if(v2 != null)
exitVenue(5L, 7L, tempDate2);
Visit visit2 = new Visit(5L, 7L, tempDate2);
ofy().save().entity(visit2).now();
}
public void exitVenue(Long userID, Long venueID, Date exitDate) {
Visit visit = ofy().load().type(Visit.class)
.filter(Visit.USER_ID, userID)
.filter(Visit.VENUE_ID, venueID)
.filter(Visit.EXIT_DATE, null).first().get();
if(visit == null){
log.info("ERROR : User " + userID + " exited venue " + venueID + ", but Visit was not found");
return;
}
visit.setExitDate(exitDate);
ofy().save().entity(visit).now();
}
the problem is that when I preform all this operation for the second time, it not always finds that there is already a visit in the datastore (every second test, or so). And I'm confused isn't 'now()' suppose to store it right away and only then to continue running ?
Thank you very much for your help, Dan
This is happening because GAE Datastore is eventually consistent: when you create/update an entity, the method returns immediately, but indexes are still being built asynchronously. Since queries rely on indexes you do not see the changes immediately.
Also, this has nothing to do with objectify - this is a property of the underlying datastore. The synchronous write (
.now()
) waits for the commit phase to finish , while asynchronous returns immediately even before that.