Dominic Holt
Dominic Holt

Reputation: 162

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();

    }

}

Upvotes: 1

Views: 194

Answers (1)

Dominic Holt
Dominic Holt

Reputation: 162

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

Upvotes: 1

Related Questions