【发布时间】:2014-12-12 11:11:24
【问题描述】:
我注意到 Wicket 的 LoadableDetachableModel (LDM) 会根据设计(通过 RequestCycle.processRequestAndDetach())分离每个请求。这在特定情况下可能会导致性能问题,我希望在保留缓存数据的同时仍然使用 LDM 的优势。
假设您有一个带有 id 的实体的详细信息页面。该页面分为选项卡 (AjaxTabbedPanel)。
如果您打开页面,则会从 DB 中读取给定 id 的实体(进入 LDM)。
如果单击第二个选项卡,模型已经分离,将再次重新加载。
在我的情况下这不是必需的,因为我不想刷新每个请求的数据。
我想要页面上的 LDM,以便页面历史记录能够正常工作(只有实体 ID 会被序列化并按需重新加载数据)。
那么如何修复不必要的重载?
我想出了两个解决方案:
- 将 LDM 包装到静态模型中,使其不会自动分离,仅在需要时手动分离(=重新加载)。
- 实现 LDM 的子实现,它将保留瞬态数据并仅在为 null 时重新加载(如恢复序列化页面时)。然后可以重复使用此通用模型。
我认为在检票口中已经为此实施了解决方案,但我没有找到任何解决方案。您知道实现此目的的任何其他(标准)方法吗?
非常感谢您的回答。
PS:2) 的示例实现
private class MyEntityModel extends LoadableDetachableModel<MyEntity> {
private String entityId;
private transient MyEntity modelObject;
public MyEntityModel(String entityId) {
this.entityId = entityId;
}
//call this for explicit reload
public void forceDetach() {
modelObject = null;
detach();
}
@Override
protected MyEntity load() {
if (modelObject != null) {
return modelObject;
}
MyEntity entity = getData(entityId);
modelObject = message;
return message;
}
}
更新: 看来我原来的问题还不够清楚。对此感到抱歉。 当前行为:
- 使用作为参数传递的 entityID 加载检票口页面
- 创建了一个新的 LDM 实例,并将 entityID 传递给它
- 当(在响应呈现期间)调用 LDM.getObject() 时,从数据库中加载实体
- 响应呈现后,调用 LDM.detach()
- 加载了带有 ajax 控件的页面
- 当用户点击任何控件(如选项卡开关)时,会向服务器生成一个新请求
- 服务器交换选项卡,尝试用数据填充新选项卡,因此它调用已在 4. 中分离的 LDM.getObject(),并再次加载数据
- 响应发送到客户端并调用 LDM.detach()
期望的行为: 广告 4 - 当 LDM.detach() 被调用时,瞬态模型对象被保留 广告 7 - 如果瞬态模型对象仍在内存中,请使用它。否则加载数据
上面我描述了两种方法,如何实现这种行为。有什么标准或者更好的方法吗?
【问题讨论】:
-
看看
AbstractReadOnlyModel:ci.apache.org/projects/wicket/apidocs/6.x/org/apache/wicket/… -
如果数据没有在某些 Ajax 请求中分离,那么如果下一个请求是通过 BookmarkablePageLink 到另一个页面,那么这个数据根本不会从第一页分离,并将与其余的一起序列化.当使用 LDM 时,payload 很可能没有实现 java.io.Serializable!
-
@RobertNiestroj 这可能是最正确的答案。 LDM 似乎真的被实现为在每次请求后分离,所以改变它(不分离)可能是一种误用。所以我需要的是一个具有瞬态对象的模型,它是不可分离的,并且在瞬态对象为空时(例如反序列化之后)会重新加载。 AbstractReadOnlyModel 可能更适合这个。
-
我遇到了同样的问题,下面提供的答案不是解决这个问题的方法。
-
嗨,到目前为止,我没有看到任何标准模型实现包含在检票口中。 LDM 确实适用于不同的用例,因此您可能需要实现自己的东西。您可以使用我的代码(简单、有效,但扩展了 LDM,这在语义上不正确),或扩展其他代码(如 AbstractReadOnlyModel,...)。
标签: ajax performance wicket