Google数据存储 - 更新实体时出现问题 [英] Google Datastore - Problems updating entity

查看:123
本文介绍了Google数据存储 - 更新实体时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



根据 GAE文档中的示例我正在尝试更新实体,如下所示:

  //持久性和业务逻辑
PersistenceManager pm = PMF.get()。getPersistenceManager();

//得到它
NickName n = pm.getObjectById(NickName.class,nicknameId);

//更新字段
n.givenName =新名称;
n.nickName =新昵称;
n.timeStamp = new Date();

//关闭管理器来保存更改
pm.close();

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



同时,我发现如果我使用相同的ID创建一个新的实体,那么这些更改会持久:

  //持久性和业务逻辑
PersistenceManager pm = PMF.get()。getPersistenceManager();

NickName n =新的NickName(新名称,新昵称,新Date());

//设置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 =昵称;
this.timeStamp = timestamp;
}

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

@Persistent
public String givenName;

@Persistent
public String nickName;

@Persistent
public Date timeStamp;

$ / code>

任何帮助表示感谢!

解决方案

有一个问题可能是您直接设置字段而不是通过setter方法。我相当肯定JDO是通过设置字段设置器来工作的,以便他们通知持久层发生的任何更改。它无法直接监视对后台字段值本身的更改。所以也许试试:

  n.setGivenName(new name); 
n.setNickName(新昵称);
n.setTimeStamp(new Date());

您可以避免在创建对象时直接设置字段,因为 makePersistent() call告诉持久性管理器需要检查字段值并保存它们。尽管值得注意的是,直接设置字段值通常被认为是不好的编码风格。

另外,你是否尝试过使用JPA接口而不是JDO接口?在GAE中,它们应该是可互换的:

  EntityManager em = EMF.get(); 

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

n.givenName =新名称;
n.nickName =新昵称;
n.timeStamp = new Date();

em.merge(n);

em.close();

这给你一个明确的 merge()即使直接设置字段值,也应该调用它。


I am dusting off my google app-engine / datastore skills ... and getting stuck on something very simple.

As per the example on the GAE documentation I am trying to update an entity as follows:

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

This doesn't work (as in the changes are not persisted, but no errors or anything else)!

At the same time I found that if I create a new entity with the same ID the changes get persisted:

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

I have the feeling I already solved this the 1st time I approached app engine and the data-store.

This is what my entity looks like:

@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;
}

Any help appreciated!

解决方案

One issue may be that you are setting the fields directly instead of going through the setter methods. I'm fairly certain that JDO works by instrumenting the field setters so that they notify the persistence layer of any changes that occur. It has no way of directly monitoring changes to the backing field values themselves. So maybe try:

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

You're able to get away with setting the field directly when you create the object because the makePersistent() call tells the persistence manager that is needs to inspect the field values and save them. Though it's worth noting that setting field values directly like this is generally considered to be poor coding style.

Also, have you tried using the JPA interface instead of the JDO interface? In GAE they should be interchangeable:

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

This gives you an explicit merge() call which should work even with setting the field values directly.

这篇关于Google数据存储 - 更新实体时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆