【问题标题】:How GWT RequestFactory .edit() and sending of deltas work and how to tweak itGWT RequestFactory .edit() 和发送增量如何工作以及如何调整它
【发布时间】:2013-08-07 23:44:53
【问题描述】:

我注意到当我调用

    SomeProxy proxyNew = someRequestContext.edit(proxyOld);
    proxyNew.setSomething(somethingNew);
    someRequestContext.mySaveMethod(proxyNew).fire();

返回的实体
    @Override //from Locator<SomeEntity ,IdClass>
    public SomeEntity find(Class<? extends SomeProxy > clazz, IdClass id) {
    ...
    }

在调用保存方法时在服务器中使用,并且仅将那些 proxyNew 的属性/距离变量值传输到服务器实现mySaveMethod(SomeEntity entity)与返回的实体相比是新的。

现在。我知道有一些比较是为了只为服务器端提供增量,因此通信效率很高,但我认为它在某种程度上被实现 public SomeEntity find(Class&lt;? extends SomeProxy &gt; clazz, IdClass id) 所需的额外处理/传输时间所抵消,它从数据库中检索实体对象。

我现在的问题是,如何在通过无状态会话 bean 公开持久性服务的系统中正确实现这一点,无状态会话 bean 为 GWT 服务器端 servlet/DAO 对象提供服务。以实现最高效率和最低等待时间的方式正确实施。也有人可以更详细地向我解释这个 RequestFactory 方面/过程吗?

我的示例:我从持久层中检索 OrganizerEntry 实体某天跨度 - 一周。

所以方法像 retrieveOrganizerEntries(Date from, Date to) 在持久层中被调用。

然后我看到对于每个要发送到客户端层的OrganizerEntry实体对象,都会进行另一个查询,例如retrieveOrganizerEntry(int id)

所以不仅相同的对象被查询了两次,而且第二次被一个一个地查询,效率非常低。

如何改进?我是否应该以某种方式将第一次查询的结果缓存在 DAO/servlet 对象中并让public SomeEntity find(Class&lt;? extends SomeProxy &gt; clazz, IdClass id) 搜索缓存?是否可以实现此方法返回null 或 新创建的空实体 (new OrganizerEntity()) 并且在从客户端调用持久/保存方法之前只是设置每个属性/实例变量值?

我在哪里可以找到有关这些内容的更多示例和说明?因为http://www.gwtproject.org/doc/latest/DevGuideRequestFactory.html 在我看来不是很累。

【问题讨论】:

    标签: jakarta-ee gwt requestfactory


    【解决方案1】:

    1.) 关于rf 的内部结构,你可以参考这个document。但我想 Thomas Broyer 会更详细地回应这个问题。

    基本流程如下:

    • 通过 setter 修改的属性将传输到服务器。
    • 服务器使用find() 检索实体并调用相应的setters(无论您在客户端上调用什么)。
    • 验证规则已处理
    • 实体被传递给您的服务方法。

    2.) 使用RF,您需要one session per http request 又名OpenSessioninview pattern。 . 持久层的第一级缓存(即 Hibernate)应该对find() 进行多次冗余调用非常有效,因此您通常只会在会话的生命周期内访问数据库一次。

    3.) 如果您不关心客户端上的EntityProxyChange 事件,您可以覆盖LocatorisLive() 方法并返回true(有关更多详细信息,请参阅here)。这也可能是当您检索OrganizerEntry 实例列表时调用find() 方法的原因,因为对于每个OrganizerEntry RF 通过调用本身调用find() 的'isLive()' 检查它是否仍然存在.

    【讨论】:

    • 感谢 Uemit 的精彩解释。所以有两种方法可以走:A)每个http请求都有一个带有持久层的会话/EntityManager——这会涉及一些拦截器或有状态的会话bean吗?现在对 JPA 的调用是通过无状态会话 bean 进行 CRUD 操作的。 B) 通过覆盖isLive() 来“关闭”对find() 的调用以始终返回true。我想知道,我用这种方法在这里失去了什么?问题是什么? 'EntityProxyChange' 事件到底是什么?
    • A.) 是的,OpenSessionview 模式是正确的方法。不幸的是,我没有使用 JavaEE 的经验,但是使用 Spring 你只需要添加一个 servlet 过滤器。
    • B.) EntityProxyChange 事件在您想要通知客户端实体已更改/删除时很有用。 (有关详细信息,请参阅here)。如果您覆盖isLive() 并返回true,您将不会在客户端上获得这些事件。大多数人可能并不关心那些Events
    • 因此,当实体发生更改时,我会牺牲从服务器端接收到客户端的事件,以便我可以拥有更简单的架构和更快的加载(即使使用OpenSessionView,也必须增加一些开销,oder?)。无论如何,拥有Events 有什么好处?如果数据被多个用户同时编辑?我必须说覆盖isLive() 有所帮助,但我仍然感到困惑,并且即使在坚持Entity 时,也根本不会调用t understand how RT works. Now I dont 看到find()
    • 正确响应事件(即,一个实体被另一个用户删除)并保持系统和用户体验简单是相当困难的。这可能是大多数人不依赖EntityProxyChange 事件的原因。最后一个保存实体“获胜”的用户是一种常见的方法。即使您覆盖 isLive() 方法 find() 也应该在持久化实体时调用。如果它没有被调用,那么我想什么都没有改变(没有调用 setter)。
    猜你喜欢
    • 2011-08-04
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    相关资源
    最近更新 更多