Google app engine GAE JDO persistencemanager GetObjectById是否不返回此类对象?
我一直在尝试运行我的GAE代码。使用encodedKey检索用户时遇到问题: 我有一个用户数据管理器类,它使用singleton PMF管理我的所有CRUD事务 我有用户,使用编码字符串作为我的密钥:Google app engine GAE JDO persistencemanager GetObjectById是否不返回此类对象?,google-app-engine,jdo,Google App Engine,Jdo,我一直在尝试运行我的GAE代码。使用encodedKey检索用户时遇到问题: 我有一个用户数据管理器类,它使用singleton PMF管理我的所有CRUD事务 我有用户,使用编码字符串作为我的密钥: public class Users implements Serializable { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) @Extension(vendorName = "datanucle
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.
我不明白,为什么它不为我的新实体生成一个新密钥?由于所有这些问题,我正在考虑返回键。我认为encodedKey将更具可移植性,因为我正在使用GAE服务器向我的Android客户端提供数据。您需要使用
@PersistenceCapable
注释来注释您的类。有关更多信息,请查看当您将该字段标记为生成其值时,调用setEncodedKey()有什么意义?(使用valueStrategy=IDENTITY)。如果生成了某些内容(当插入数据库时,就像那样),那么传递到setEncodedKey的值将被忽略,这一点通过调用pm.getObjectId(obj)可以清楚地看到。我已经注释了@PersistenceCapable,只是上面的代码中没有显示它。gae/J有类似这样的测试,它在这里被持久化,并且工作正常,所以唯一的结论是你没有做它所做的