Reapz Reapz - 3 months ago 7
Java Question

Can't re-create Google Datastore Key in database using same id

I'm creating an app that has two main types right now: User and Trip

Each User entity is unique, whereas a User could have many potential Trip entities.

Couple problems that are all related:

1) Using the class I've written below I can create a new User (addUser method), but the app does not recognise that the User exists the second time through, it just continually creates a new user (and replaces the previous one because they have the same name).

2) Deleting a trip (deleteTrip method) does not work even though the Key should already exist in the datastore

Somehow, despite this I can successfully add Trip types and retrieve them out of the datastore using the uniqueID that I provide. What am I doing wrong with these Keys?

Here's my code:

public class Persistence {

static Logger logger = Logger.getLogger(Persistence.class.toString());
private static DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();


public static ArrayList<Trip> getTrips(String uniqueID) {
ArrayList<Trip> trips = new ArrayList<Trip>();

Key ancestorKey = KeyFactory.createKey("User", uniqueID);

Query query = new Query("Trip", ancestorKey);
List<Entity> tripsFromCloud = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));

for( int i = 0 ; i < tripsFromCloud.size() ; i++ ) {
Entity tripEntity = tripsFromCloud.get(i);
String city = tripEntity.getProperty("city").toString();
String leaveDate = "";
String returnDate = "";

if( tripEntity.getProperty("leaveDate") != null ) {
leaveDate = tripEntity.getProperty("leaveDate").toString();
}

if( tripEntity.getProperty("returnDate") != null ) {
returnDate = tripEntity.getProperty("returnDate").toString();
}

Trip t = new Trip();
t.setCity(city);
t.setArriving(leaveDate);
t.setReturning(returnDate);
trips.add(t);

}

return trips;
}

public static void addTrip(String uniqueID, String city, String leaveDate, String returnDate) {


Key ancestorKey = KeyFactory.createKey("User", uniqueID);

Date date = new Date();

Key key = KeyFactory.createKey(ancestorKey, "Trip", date.toString() + uniqueID);

Entity newTrip = new Entity(key);

newTrip.setProperty("city", city);
newTrip.setProperty("leaveDate", leaveDate);
newTrip.setProperty("returnDate", returnDate);


datastore.put(newTrip);

}

public static void deleteTrip(String uniqueID, String city) {

Key key = KeyFactory.createKey("User", uniqueID);

datastore.delete(key);

}

public static void addUser(String uniqueID) {

Transaction txn = datastore.beginTransaction();
Key userKey = KeyFactory.createKey("User", uniqueID);
Entity user = null;
try {
user = datastore.get(userKey);
logger.log(Level.INFO, "Found user: " + user.getKey().getName());
} catch (EntityNotFoundException e) {
user = new Entity(userKey);
user.setProperty("id", uniqueID);
user.setProperty("about", "");
userKey = datastore.put(user);
logger.log(Level.INFO, "Created new user with id: " + uniqueID);
}
txn.commit();

}

}

Answer

As far as I know, since I don't know what each unique Key is for each Trip, I had to run a Query first to get the Entity from which I procured the Key like below:

private static Key getKeyForCity(String uniqueID, String city) {

    Key ancestorKey = KeyFactory.createKey("User", uniqueID);

    Query query = new Query("Trip", ancestorKey);
    query.addFilter("city", FilterOperator.EQUAL, city);
    Entity trip = datastore.prepare(query).asSingleEntity();

    return trip.getKey();
}

Once I had the proper Key it was easy to delete the Entity:

public static void deleteTrip(String uniqueID, String city) {

    Key key = getKeyForCity(uniqueID, city);

    datastore.delete(key);

}

My issues with adding a User magically cleared up after upgrading from App Engine 1.6 to 1.9