Jochen Jochen - 2 months ago 9
Java Question

findRecord in Google CloudDatastore with Objectify

I want to use Objectify to query Google Cloud Datastore. What is an appropriate way to find a record based on a known key-value pair? The record is in the database, I verified this by Google's Datastore viewer.

Here is my method stub, which triggers the NotFoundException:

@ApiMethod(name="getUser")
public User getUser() throws NotFoundException {
String filterKey = "googleId";
String filterVal = "jochen.bauer@gmail.com";
User user = OfyService.ofy().load().type(User.class).filter(filterKey, filterVal).first().now();
if (user == null) {
throw new NotFoundException("User Record does not exist");
}
return user;
}


Here is the User class:

@Entity
public class User {
@Id
Long id;
private HealthVault healthVault;
private String googleId;

public User(String googleId){
this.googleId = googleId;
this.healthVault = new HealthVault();
}

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public HealthVault getHealthVault() {
return healthVault;
}
public void setHealthVault(HealthVault healthVault) {
this.healthVault = healthVault;
}
public String getGoogleId() {
return googleId;
}
public void setGoogleId(String googleId) {
this.googleId = googleId;
}
}

Answer

I think it fails because of transaction. You need to make a transctionless call like:

User user = OfyService.ofy().transactionless().load().type(User.class).filter(filterKey, filterVal).first().now();

More info about transactions on App Engine: https://cloud.google.com/appengine/docs/java/datastore/transactions https://github.com/objectify/objectify/wiki/Transactions

EDIT Your object needs @Index annotation. It will add field to datastore index. Only properties that are in the index can be searchable. Filter method is one of them.

@Id
Long id;
@Index
private HealthVault healthVault;
@Index
private String googleId;

P.S. delete your object with googleId jochen.bauer@gmail.com and write it again to database after you updated your entity. And objectify will find it.