Google app engine appengine数据存储中的键和唯一行

Google app engine appengine数据存储中的键和唯一行,google-app-engine,primary-key,google-cloud-datastore,Google App Engine,Primary Key,Google Cloud Datastore,我对java和google appengine数据存储的使用还是相当陌生的 我可以将数据放入数据存储并将其从数据存储中取出,并且我正在尝试将其设置为用户不能被输入两次。 由于数据存储上没有唯一的索引,我将用户电子邮件地址的散列设置为primarykey 奇怪的是,当我多次输入相同的数据时,它被输入到数据存储中(我认为这会返回一个错误,或者什么也没做) 因此,当我将emailhash设置为“2”进行测试时,然后多次运行insert脚本,然后查询其中的_emailhash='2',我得到3个结果 这

我对java和google appengine数据存储的使用还是相当陌生的

我可以将数据放入数据存储并将其从数据存储中取出,并且我正在尝试将其设置为用户不能被输入两次。 由于数据存储上没有唯一的索引,我将用户电子邮件地址的散列设置为primarykey

奇怪的是,当我多次输入相同的数据时,它被输入到数据存储中(我认为这会返回一个错误,或者什么也没做)

因此,当我将emailhash设置为“2”进行测试时,然后多次运行insert脚本,然后查询其中的_emailhash='2',我得到3个结果

这里是我定义用户的类

@Entity public class user { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long _uid; @PrimaryKey private String _emailHash; private String _firstName; private String _lastName; private String _email; private String _password; public Long getUid() { return _uid; } public String getEmailHash(){ return _emailHash; } public void setEmailHash(String emailHash) { _emailHash = emailHash; } public String getFirstName() { return _firstName; } public void setFirstName(String firstName) { _firstName = firstName; } public String getLastName() { return _lastName; } public void setLastName(String lastName) { _lastName = lastName; } public String getEmail() { return _email; } public void setEmail(String email) { _email = email; } public String getPassword() { return _password; } public void setPassword(String password) { _password = password; } } @实体 公共类用户 { @身份证 @GeneratedValue(策略=GenerationType.IDENTITY) 私人长途电话; @主键 私有字符串\u emailHash; 私有字符串_firstName; 私有字符串_lastName; 私人字符串\u电子邮件; 私有字符串\u密码; 公共长getUid() { 返回uid; } 公共字符串getEmailHash(){ 返回电子邮件哈希; } public void setEmailHash(字符串emailHash) { _emailHash=emailHash; } 公共字符串getFirstName() { 返回_firstName; } public void setFirstName(字符串firstName) { _名字=名字; } 公共字符串getLastName() { 返回_lastName; } public void setLastName(字符串lastName) { _lastName=lastName; } 公共字符串getEmail() { 返回电子邮件; } 公用电子邮件(字符串电子邮件) { _电子邮件=电子邮件; } 公共字符串getPassword() { 返回密码; } public void setPassword(字符串密码) { _密码=密码; } } 谷歌的文档说明如下

an entity ID ("key name") provided by the application when the object is created. Use this for objects without entity group parents whose IDs should be provided by the application. The application sets this field to the desired ID prior to saving. import javax.jdo.annotations.PrimaryKey; // ... @PrimaryKey private String name; 创建对象时应用程序提供的实体ID(“密钥名”)。对于没有实体组父对象(其ID应由应用程序提供)的对象,使用此选项。应用程序在保存之前将此字段设置为所需的ID。 导入javax.jdo.annotations.PrimaryKey; // ... @主键 私有字符串名称; 在

有没有更好的方法来保证uniques?还是每次插入前都必须检查该值是否存在

--------------------------更新---------------------------------------------- 根据Dmitri的回答,我把JPA和JDO混为一谈(或者至少把两者混淆了)。现在我已经解决了这个问题,我的散列电子邮件定义如下

@Id @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") private String _emailHash; @GeneratedValue(strategy = GenerationType.IDENTITY) private Long _uid; @身份证 @扩展名(vendorName=“datanucleus”,key=“gae.encoded pk”,value=“true”) 私有字符串\u emailHash; @GeneratedValue(策略=GenerationType.IDENTITY) 私人长途电话; 不幸的是,在尝试创建具有

$pm = EMF::createEntityManager(); $user = new user(); $user->setEmailHash('5'); $user->setFirstName('test5'); $user->setLastName('test5'); $user->setEmail('test5'); $pm->persist($user); $pm=EMF::createEntityManager(); $user=新用户(); $user->setEmailHash('5'); $user->setFirstName('test5'); $user->setLastName('test5'); $user->setEmail('test5'); $pm->persist($user); 我得到以下错误

Invalid primary key for com.nextweeq.scheduler.user. The primary key field is an encoded String but an unencoded value has been provided com.nextweeq.scheduler.user的主键无效。主键字段是编码字符串,但提供了未编码的值
到目前为止,我的搜索返回了一些关于指定keyname的信息,但我还没有找到解决方案

您所指的文档是关于JDO的,而您的代码似乎在使用JPA,其中@Id与@PrimaryKey在JDO中扮演的角色相同

您所指的文档是关于JDO的,而您的代码似乎在使用JPA,其中@Id与@PrimaryKey在JDO中扮演的角色相同

您可以使用键来检索数据:

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

Key k = KeyFactory.createKey(user.class.getSimpleName(), "Alfred.Smith@example.com");

PersistenceManager pm = PMF.get().getPersistenceManager();
user usr = pm.getObjectById(user.class, k);

来源:

您可以使用键检索数据:

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

Key k = KeyFactory.createKey(user.class.getSimpleName(), "Alfred.Smith@example.com");

PersistenceManager pm = PMF.get().getPersistenceManager();
user usr = pm.getObjectById(user.class, k);

来源:

感谢Dmitri,这可能是第一个问题,但现在我发现与使用“数据存储中的对应实体”没有名称相关的错误,我不确定我是否完全理解。感谢Dmitri,这可能是第一个问题,但是现在我发现了一些错误,这些错误与使用“数据存储中的对应实体”没有名称有关,我不确定我是否完全理解。我不确定你从克里斯蒂安那里得到了什么。如何使用密钥检索与将数据用作密钥相关的数据?我试图将用户数据设置为密钥,而不是基于密钥检索数据。同样,was检索也可以用作密钥。Key k=KeyFactory.createKey(user.class.getSimpleName(),“Alfred。Smith@example.com"); 引用google文档:“可以分别使用KeyFactory类的keyToString()和stringToKey()方法将键转换为字符串表示形式和从字符串表示形式转换为键(请注意,这不同于Key类的toString()方法,后者返回适合调试的人类可读值)。”我不知道你在说什么克里斯蒂安。如何使用密钥检索与将数据用作密钥相关的数据?我试图将用户数据设置为密钥,而不是基于密钥检索数据。同样,was检索也可以用作密钥。Key k=KeyFactory.createKey(user.class.getSimpleName(),“Alfred。Smith@example.com"); 引用google文档:“可以分别使用KeyFactory类的keyToString()和stringToKey()方法将键转换为字符串表示形式和从字符串表示形式转换为键(请注意,这不同于Key类的toString()方法,后者返回适合调试的人类可读值)。”