【发布时间】:2012-10-11 15:45:00
【问题描述】:
我一直在尝试运行我的 GAE 代码。我在使用 encodeKey 检索用户时遇到问题:
我有这个用户数据管理器类,它使用单例 PMF 管理我的所有 CRUD 事务。
我有用户,使用编码的字符串作为我的密钥:
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 ----
我在 DM 类中有这个 createUser 方法
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();
}
}
问题在于要检索的这段代码:
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;
}
它给了我以下错误:
SEVERE: javax.jdo.JDOObjectNotFoundException: No such object
FailedObject:Users("t")
NestedThrowables:org.datanucleus.exceptions.NucleusObjectNotFoundException: No such object
无论如何,“t”是虚拟用户的电子邮件。
如何使用encodedKey 来获取使用PMF 的实体? 目前,我正在求助于使用电子邮件和查询进行识别,但是按键获取对象应该可以工作。
编辑:
我对模型对象进行了以下更改:
@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;
基于此和谷歌的文档:
应用程序可以在保存之前使用带名称的键填充此值,也可以将其保留为空。如果编码的键字段为空,则在保存对象时,该字段将填充系统生成的键。
我认为简单地坚持这个就可以了:
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();
}
}
但是,没有这样的运气,无论我是否先设置键名,都会引发此错误:
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.
我不明白,为什么它没有为我的新实体生成新密钥?由于所有这些问题,我正在考虑回到 Key。我认为 encodedKey 会更便携,因为我使用 GAE 服务器向我的 Android 客户端提供数据。
【问题讨论】:
标签: google-app-engine jdo