ключи и уникальные строки в хранилище данных appengine - PullRequest
1 голос
/ 12 января 2010

Я все еще новичок в работе с Java и хранилищем данных Google Appengine.

Я могу ввести данные и извлечь их из хранилища данных, и я пытаюсь сделать так, чтобы пользователь не мог войти дважды. Поскольку в хранилище данных нет уникального индекса, я задаю хэш адреса электронной почты пользователя в качестве первичного ключа.

Странно, когда я вводил одни и те же данные несколько раз, они вводятся в хранилище данных (которое, я думал, вернуло ошибку или ничего не сделало).

Поэтому, когда я устанавливаю свой emailhash на '2' для тестирования, а затем запускаю скрипт вставки несколько раз, и на запрос WHERE _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;
 }
}

Документация Google гласит следующее

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;

в http://code.google.com/appengine/docs/java/datastore/creatinggettinganddeletingdata.html

Есть ли лучший способ гарантировать уникальность? Или мне нужно проверять, существует ли значение каждый раз перед вставкой?

-------------------------- UPDATE -------------------- -------------------------- Согласно ответу Дмитрия, я смешивал JPA и JDO (или, по крайней мере, путался между ними). Теперь, когда я с этим разобрался, мое хешированное определение электронной почты выглядит следующим образом

@Id
 @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
 private String _emailHash;

 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long _uid;

К сожалению, при попытке создать пользователя с

$pm = EMF::createEntityManager();
 $user = new 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

Пока мои поиски возвращают что-то об указании имени ключа, но я пока не нашел решения.

Ответы [ 2 ]

1 голос
/ 12 января 2010

Документация, на которую вы ссылаетесь, касается JDO, в то время как ваш код использует JPA, где @Id играет ту же роль, что и @PrimaryKey в JDO

.
0 голосов
/ 12 января 2010

Вы можете использовать ключи для извлечения данных:

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);

Источник: appengine docs

...