Wicket 9.10.0中Panel替换组件引发可分离模型异常分离重载问题
Wicket LoadableDetachableModel 组件替换时异常触发重复加载问题
问题现象
- 基于Wicket官方Hello示例复现了疑似框架逻辑异常的问题,当前正在排查解决方案。
- 页面定义了可分离模型供内部多个Panel、组件共用,模型加载过程会执行多次数据库查询,无意义场景下的重复加载会造成严重的性能开销,完全无法接受。
- 正常请求流程:页面内共20个Panel复用同一个模型实例,首次请求时所有Panel创建完成后共用已加载完成的模型数据,仅触发1次
load()方法,请求结束后模型正常完成分离。 - 异常触发流程:修改业务逻辑、替换所有Panel内的组件时出现异常,每一次组件移除操作都会触发模型分离,进而导致模型重复重载。
最简复现代码
说明:代码中
getObject()方法的调用位置仅用于标记模型触发加载、或已处于加载状态的时机。
首页类代码
private static final long serialVersionUID = 1L; Panel panel; IModel<String> model = new LoadableDetachableModel<String>() { @Override protected String load() { return "test"; } @Override protected void onDetach() { super.onDetach(); } }; public HomePage(final PageParameters parameters) { super(parameters); model.getObject(); add(new Label("version", getApplication().getFrameworkSettings().getVersion())); panel = new HomePanel("homePanel"); // 首次执行无问题 panel.addOrReplace(new Label("test", model)); add(panel); // 复用已加载的模型 model.getObject(); // 此处会触发模型分离 panel.addOrReplace(new Label("test", model)); // 此处触发异常:模型被重新加载 model.getObject(); }
自定义Panel类代码
import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; public class HomePanel extends Panel { Label label; public HomePanel(String id) { super(id); } public HomePanel(String id, IModel<String> model) { super(id, model); } }
完成上述类编写后,将Panel实例添加至首页即可复现问题。
待确认问题
- 该现象是否为Wicket框架的正常设计逻辑?
- 替换子组件时为什么会触发父页面持有的模型分离,而非仅分离子组件自身关联的模型?
内容的提问来源于stack exchange,提问作者cyril
相关产品推荐
相关产品推荐

