Google Datastore - Проблемы с обновлением объекта - PullRequest
3 голосов
/ 30 июня 2011

Я стираю свои навыки работы с google app-engine / datastore ... и зацикливаюсь на чем-то очень простом.

В соответствии с примером в документации GAE Я пытаюсьобновите сущность следующим образом:

// persistence and business logic
PersistenceManager pm = PMF.get().getPersistenceManager();

// get it
NickName n = pm.getObjectById(NickName.class, nicknameId);

// update fields
n.givenName = "new name";
n.nickName = "new nickname";
n.timeStamp = new Date();               

// close manager to persist changes
pm.close();

Это не работает (так как изменения не сохраняются, но нет ошибок или чего-либо еще)!

В то же время я обнаружил, что если я создаю новую сущность с тем же идентификатором, изменения сохраняются:

// persistence and business logic
PersistenceManager pm = PMF.get().getPersistenceManager();

NickName n = new NickName("new name", "new nickname", new Date());

// set id
n.id = nicknameId;

pm.makePersistent(n);

pm.close();

У меня такое чувство, что я уже решил эту проблему при первом приближенииМеханизм приложения и хранилище данных.

Вот как выглядит моя сущность:

@PersistenceCapable
public class NickName {

    public NickName(String name, String nickname, Date timestamp) {
        this.givenName = name;
        this.nickName = nickname;
        this.timeStamp = timestamp;
    }

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    public String id;

    @Persistent
    public String givenName;

    @Persistent
    public String nickName;

    @Persistent
    public Date timeStamp;
}

Любая помощь приветствуется!

1 Ответ

2 голосов
/ 30 июня 2011

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

n.setGivenName("new name");
n.setNickName("new nickname");
n.setTimeStamp(new Date()); 

Вы можете избежать установки поля непосредственно при создании объекта, потому что вызов makePersistent() сообщает диспетчеру сохранения, который должен проверить значения поля и сохранитьих.Хотя стоит отметить, что установка значений полей напрямую, как это обычно считается плохим стилем кодирования.

Кроме того, вы пытались использовать интерфейс JPA вместо интерфейса JDO?В GAE они должны быть взаимозаменяемыми:

EntityManager em = EMF.get();

NickName n = em.find(NickName.class, nicknameId);

n.givenName = "new name";
n.nickName = "new nickname";
n.timeStamp = new Date();    

em.merge(n);

em.close();

Это дает вам явный вызов merge(), который должен работать даже при прямой установке значений поля.

...