2

再会!

我试图在 GWT 2.4 中实现并发保存。有一个用户案例:

  1. 用户 John 和 Jim 打开一个实体进行编辑
  2. John 保存他的更改。一切正常。
  3. Jim 保存他的更改。系统询问是否覆盖

    一种。Jim 不想覆盖,系统只是刷新页面上的实体

    湾。否则,如果 Jim 想要保存他的更改,则必须保留更改并且 John 的更改将被销毁。(仅留在更改历史中)

所以我对3.b有问题。

public void save(MyEntityProxy entity){
    MyRequest rContext = (MyRequest) driver.flush();
    MyProxy myEntity = (MyProxy) rContext.edit(entity);
    entitySave(rContext, (MyProxy) myEntity, false);
}

private void entitySave(MyRequest rContext, final MyProxy myEntity, boolean overwrite){
    GWT.log("SAVE ENTITY WITH NAME = " + myEntity.getName());
    rContext.persist(myEntity, entityVersion, overwrite)
    .fire(new Receiver<MyProxy>() {
        @Override
        public void onSuccess(MyProxy response) {
            goToModel();
        }
        @Override
        public void onFailure(ServerFailure error) {
            if(isConcurency(error)){
                entitySave((MyRequest)getNewRequestContext(), myEntity,true);
            }
        }
    });
}

/*This is a method from MyService for persisting*/
public MyProxy persist(MyProxy entity, Long version, boolean overwrite) {
    LOG.info("PERSISTS ENTITY  NAME=" + entity.getName());
    if(!overwrite && !checkVersionChanged(entity, version)){    
      System.out.println("RAISE CHANGED_BY_OTHER EXCEPTION");
      throw new RuntimeException(CHANGED_BY_OTHER.name());              
    }
    entity = getEntityManager().merge(entity);
    getEntityManager().flush();
    return entity;
}

isConcurrency 是一种检查并发问题的方法,当用户在对话框中选择“覆盖”点时返回 true。

GWT 日志:

SAVE ENTITY WITH NAME = John //There is John changed name of entity
SAVE ENTITY WITH NAME = Jim  //There is John changed name of entity
SAVE ENTITY WITH NAME = Jim  //There is John overwrites entity

服务器日志:

[INFO] PERSISTS ENTITY NAME=Jim //There is John changed name of entity
[INFO] SAVE ENTITY NAME=Jim     //Persisting of John's changes. Here John finished his work
[INFO] PERSISTS ENTITY NAME=John //There is Jim changed name of entity
[INFO] RAISE CHANGED_BY_OTHER EXCEPTION   //Exception raises and dialog shows for Jim
[INFO] PERSISTS ENTITY NAME=John //Second iteration of saving. Look at the name!.

我不明白发生了什么。当 Jim 覆盖他的更改时,在客户端层一切都是正确的,但服务器层使用以前用户保存的数据。

有谁知道在这种情况下如何正确覆盖更改?

4

1 回答 1

1

当您保存以覆盖时,您将编辑与第一次发送相同的实体,然后该实体已被冻结然后RequestContext. 因此,当您将实体传递给新创建的RequestContext时,它会隐含地edit()s 它,并且由于没有对其应用任何更改,因此它会在fire()d 时向服务器发送一个空差异。因此要求服务器 1) 从数据库加载实体,2) 应用差异(即,什么都不做,因为差异是空的),然后 3) 保存实体,此时实体尚未修改最后坚持。

理想情况下,您希望与edit()第一个请求中的实体相同,并对其重新应用相同的更改,因此您将完全相同的差异发送到服务器。不幸的是,没有简单的方法来做到这一点(嗯,这取决于您将编辑过的数据放入代理中的人)。

请参阅http://code.google.com/p/google-web-toolkit/issues/detail?id=5794http://code.google.com/p/google-web-toolkit/issues/detail?id =6046

虽然很明显,RequestFactory 不是为这些用例量身定制的,它更多的是关于保存而不询问,您的应用程序提供了一种撤消更改的方法(例如登录服务器并分配一个 ID)。

于 2012-10-03T14:09:13.560 回答