【问题标题】:Google Datastore - Problems updating entityGoogle Datastore - 更新实体时出现问题
【发布时间】:2011-06-30 00:09:26
【问题描述】:

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

根据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;
}

任何帮助表示赞赏!

【问题讨论】:

  • “这行不通!”不是一个好的说法。您在控制台日志中看到的确切错误是什么?
  • 我在控制台日志中看不到任何东西 - 一切似乎都很好,但是当我查看数据存储时更改没有保留(或尝试将实体拉出,旧值仍然存在)

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


【解决方案1】:

一个问题可能是您直接设置字段,而不是通过 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() 调用,即使直接设置字段值也应该可以工作。

【讨论】:

  • 仅供参考 JDO 直接监控 public 字段更改的方法是将调用类标记为@PersistenceAware。而 JPA 没有这样的方式,所以最好坚持 JDO
  • 我会尽快试一试。我很懒,没有放任何二传手,因为这只是一个测试——谢谢你的好建议
  • @DataNucleus - JPA 和 JDO 之间的选择实际上是个人喜好问题。我个人认为 JDO 是一个相当糟糕的选择,但对每个人来说都是如此。无论如何,我不认为能够监控直接对公共字段所做的更改是选择 JDO 的令人信服的理由。在设计良好的应用程序中,您通常一开始就没有或设置公共字段。
  • 个人喜好?当然,除了 JPA 没有获取组、数据存储 txns、索引规范和许多其他东西这一事实之外。
  • @DataNucleus - JPA 的提取组等效项是 FetchType.EAGER。它绝对支持交易。你是正确的,它不能指定索引,但在大多数严肃的生产环境中,你不会在你的 ORM 类/映射中生成你的模式或索引。所以是的,个人喜好。这两种解决方案都非常成功地用于广泛的项目中。但有些事情让我怀疑你可能不是从完全中立的角度说话。
猜你喜欢
  • 2019-10-19
  • 2018-07-27
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 2021-12-11
  • 1970-01-01
相关资源
最近更新 更多