I am using Google App Engine with the Datastore interface.
Whenever I'm trying to update an entity, a whole new entity is created, this is despite the fact that I'm positive I am saving the same entity, meaning it has the same key for sure.
This is my code:
Key key=KeyFactory.createKey("user",Long.parseLong(ID));
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity entity=new Entity("user",key);
entity.setProperty // ...whatever, updating the properties
datastore.put(entity); //by putting an entity it's supposed to
// either create a new one if non exists, or update an entity if it already exists
I am sure that the key is the same during all updates as is confirmed in my admin console:
id=3001 600643316
id=3002 600643316
id=3003 600643316
a bunch of entities with the same key (600643316) is created.
The datastore only lets the app create a new entity with a String key name, not a numeric ID. Numeric IDs are system-assigned IDs. If the Key has a numeric ID but not a String key name, then the datastore will ignore it and replace it with a system-assigned numeric ID.
In your example, if ID is a string, then you can just remove the Long.parseLong() bit, or convert it back to a String. KeyFactory.createKey(String kind, String name) creates a Key with a key name.
So it seems Dan is correct and this is the correct way to do it , as explained in google's guides if you want your app to build keys from unique keys that you create you need to use strings .
"You specify whether an entity ought to use an app-assigned key name string or a system-assigned numeric ID as its identifier when you create the object. To set a key name, provide it as the second argument to the Entity constructor:
Entity employee = new Entity("Employee","asalieri");" It seems you're correct , in their example the second argument is indeed a string – user1032663
Related
Is a key value mandatory while setting up an EntityType?
This may sound a little odd but I have a case where a key is unnecessary. So I was asking myself if I can get rid of these code lines.
List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
keyProperties.add(new PropertyRef().setName("KEY"));
Key key = new Key().setKeys(keyProperties);
A key is required for an entityType in olingo and odata, because if there is no unique key for an entity then we won't be able to use getEntity (to query the data of just one entity from a given entitySet) on it , as well as navigation properties and $expand will also not behave properly.
I am stuck with geting a persisted object by its id. I am getting an error:
com.google.appengine.api.datastore.EntityNotFoundException: No entity was found matching the key: CNG("T78")
I persist the object as below to the data store:
Key cngKey = KeyFactory.createKey("CNG", jsonCNG.cNGID);
Entity cngEntity = new Entity("CNG", cngKey);
cngEntity.setProperty("cng_name", jsonCNG.cNGName);
cngEntity.setProperty("cng_type", jsonCNG.cNGType);
cngEntity.setProperty("cng_content", cng);
Here cng is a json string. I set the key with a string: cNGID. I am trying to use the same id to get the object.
Key cngKey = KeyFactory.createKey("CNG", "T78")
and end up getting the above error.
The constructor new Entity("CNG", cngKey) is defining the entity with kind and parent key. Then when you try to retrieve it you do not provide parent key: KeyFactory.createKey("CNG", "T78"). This does not work - you must either provide parent key in both places on not.
Note - defining entity parent is used when defining entity groups, which are in turn important when using transactions. You probably did not want that?
Instead you should just use new Entity(cngKey).
You don't seem to have saved it to the datastore.
Datastore.put(cngEntity);
each user can have many questions. questions can only have one user. is the following correct
Key questionKey = KeyFactory.createKey("Questions", userId);
Entity questionEntity = new Entity("Question", questionKey);
questionEntity.setProperty("questionCategory", questionCategory);
...
The given usage is wrong. For the question, you are creating key using kind and userid . This implies the corresponding entity is of Kind="Questions" and id=userid and no parents. This is wrong and you will start getting errors once you have more than 1 question for a user as they will all have the same key.
Ideally what you need is that for a question entity, declare its kind as question and parent as the user as follows :
1, If using manually generated id or name for a question , then :
Key questionKey = KeyFactory.createKey(userkey, "Questions", questionidorname);
2, If using app engine's auto generate id, then no need create key, instead create entity as:
Entity questionEntity = new Entity("Questions",
userkey)
Here userkey is the key of a user entity
I've been programming an app which uses GAE and I store the entities with a specific Key depending on the user nick logged in Google.
The problem is that I can't make a query that retrieves the entities with a specific key and sort the entities retrieved by whatever too.
I'll give some examples:
Query query = new Query("Invoice", key);
//This works; retrieved all entities that have the key
Query query = new Query("Invoice").addSort("Date", Query.SortDirection.ASCENDING);
//This works too, retrieves ALL entities sorted by the Date field.
If I mix them:
Query query = new Query("Invoice", key).addSort("Date", Query.SortDirection.ASCENDING):
//This doesn't work, and it is what I want;to retrieve the entities with the specific key and sorted
by a field (doesn't matter right know).
I am reading the docs for Key generation in app engine. I'm not sure what effect using a simple String key has over a real Key. For example, when my users sign up, they must supply a unique username:
class User {
/** Key type = unencoded string. */
#PrimaryKey
private String name;
}
now if I understand the docs correctly, I should still be able to generate named keys and entity groups using this, right?:
// Find an instance of this entity:
User user = pm.findObjectById(User.class, "myusername");
// Create a new obj and put it in same entity group:
Key key = new KeyFactory.Builder(
User.class.getSimpleName(), "myusername")
.addChild(Goat.class.getSimpleName(), "baa").getKey();
Goat goat = new Goat();
goat.setKey(key);
pm.makePersistent(goat);
the Goat instance should now be in the same entity group as that User, right? I mean there's no problem with leaving the User's primary key as just the raw String?
Is there a performance benefit to using a Key though? Should I update to:
class User {
/** Key type = unencoded string. */
#PrimaryKey
private Key key;
}
// Generate like:
Key key = KeyFactory.createKey(
User.class.getSimpleName(),
"myusername");
user.setKey(key);
it's almost the same thing, I'd still just be generating the Key using the unique username anyway,
Thanks
When you specify a string key as you are in your example, you're specifying a key name (see the docs). As such, you shouldn't be using the KeyFactory - simply set the key field as 'myusername'.
There's no performance difference between the two options, though: Internally they are stored identically; the key name is just easier to use if you're not using parent entities for this model.