I've been trying to get my GAE code running. I have problem retrieving Users with encodedKey:
I have this User Data Manager class that manage all my CRUD transactions using singleton PMF.
I have Users, using encoded String as my key:
public class Users implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String encodedKey;
@Persistent
@Extension(vendorName = "datanucleus", key = "gae.pk-id", value = "true")
private Long keyId;
--- code continues ----
I have this createUser method in DM class
public static void createUser(Users user) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Key key = KeyFactory.createKey(Users.class.getSimpleName(),
user.getEmail());
user.setEncodedKey(KeyFactory.keyToString(key));
pm.makePersistent(user);
} catch (Exception e) {
logger.log(Level.SEVERE, e.toString());
} finally {
pm.close();
}
}
And the problem is with this piece of code to retrieve:
public static Users retrieveUser(String encodedKey) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Users user = null;
try {
// Key key = KeyFactory.createKey(Users.class.getSimpleName(),
// user.getEmail());
// I tried recreating the key with user's email, but it does not work either
pm.getObjectById(KeyFactory.stringToKey(encodedKey));
} catch (Exception e) {
logger.severe(e.toString());
} finally {
pm.close();
}
return user;
}
It is giving me the following error:
SEVERE: javax.jdo.JDOObjectNotFoundException: No such object
FailedObject:Users("t")
NestedThrowables:org.datanucleus.exceptions.NucleusObjectNotFoundException: No such object
"t" is the dummy user's email, anyway.
How do I use the encodedKey to get the entity using PMF? Currently, I am resorting to identifying using email and query, but getting object by key should work.
Edits:
I made the following changes to my model object:
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String encodedKey;
@Persistent
@Extension(vendorName="datanucleus", key="gae.pk-name", value="true")
private String keyName;
Based on this and google's documentation:
The app can populate this value prior to saving using a key with a name, or it can leave it null. If the encoded key field is null, the field is populated with a system-generated key when the object is saved.
I thought that simply persisting this would work:
public static void createUser(Users user) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
user.setKeyName(user.getEmail());
pm.makePersistent(user);
} catch (Exception e) {
logger.log(Level.SEVERE, e.toString());
} finally {
pm.close();
}
}
But, no such luck, it throws me this error whether or not I set the keyname first:
SEVERE: javax.jdo.JDOFatalUserException: Invalid primary key for entity.Users. Cannot have a null primary key field if the field is unencoded and of type String. Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.
NestedThrowables:
org.datanucleus.exceptions.NucleusFatalUserException: Invalid primary key for entity.Users. Cannot have a null primary key field if the field is unencoded and of type String. Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.
I don't get it, why is it not generating a new key for my new entity? I'm thinking of going back to Key due to all these problems. I thought encodedKey will be more portable because I'm using the GAE server to serve data to my Android client.
What's the point in calling setEncodedKey() when you marked that field to have its value generated? (with the valueStrategy=IDENTITY). If something is generated (when inserted in the DB, like that is), then your value passed in to setEncodedKey is ignored, as clearly seen by calling pm.getObjectId(obj).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With