Google数据存储区 - 更新实体时出现问题

时间:2011-06-30 00:09:26

标签: java google-app-engine google-cloud-datastore jdo

我正在清除我的谷歌应用程序引擎/数据存储技能...并且陷入非常简单的事情。

根据the example on the GAE documentation我正在尝试更新实体,如下所示:

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

这不起作用(因为更改不会保留,但没有错误或其他任何内容)!

与此同时,我发现如果我创建一个具有相同ID的新实体,则更改将保持不变:

// 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 个答案:

答案 0 :(得分:2)

一个问题可能是您直接设置字段而不是通过setter方法。我非常确定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()调用,即使直接设置字段值也应该有效。