我有一个像这样的“extendedDataTable”:
<h:form>
<rich:extendedDataTable id="someTbl"
value="#{someBean.allData}"
var="dataItem"
selection="#{dataSelectionListener.selection}"
selectionMode="single">
<a4j:ajax execute="@form"
render="@none"
event="selectionchange"
listener="#{dataSelectionListener.onSelectionChange}"/>
<rich:column>
<h:outputText value="#{dataItem.name}"/>
</rich:column>
</rich:extendedDataTable>
</h:form>
和托管bean:
@Named
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
public List<DataItem> getAllData() {
// Getting data from DB
return someService.getAllData();
}
}
dataSelectionListener
也是托管bean,范围为“session”。
每当我在表格中选择某一行时,方法getAllData
会被调用两次(在调用方法onSelectionChange
之后再进行调用)。它会导致两个不需要的查询到DB。
解决此问题的正确方法是什么?
很抱歉,如果我的问题有些愚蠢,请提前致谢。
答案 0 :(得分:0)
我认为您的问题与@RequestScoped
注释有关。请求范围意味着该对象被定义为附加到HttpRequest对象的属性并共享其生命周期。当应用程序容器接受来自客户端的HTTP请求时,将创建HttpRequest对象。当容器完成对该请求的响应传输时,它被有效地销毁(超出范围)。当新的HTTP请求进入时,会创建一个新的请求范围对象。因此,您希望在HTTP请求之间存在的任何内容都必须放在较长寿的范围内(例如会话范围),或者必须将数据作为响应的一部分发回,以便将其发送返回作为下一个请求的一部分。
答案 1 :(得分:0)
经过简短的研究(感谢BalusC博客中的旧article)我发现在JSF世界中,为表提供数据的方法的双重调用是可行的(在阶段{{期间第一次调用getter) 1}}和第二 - 在阶段APPLY_REQUEST_VALUES
期间)。所以我真的不应该使用带有范围“请求”的bean。据我所知,这种情况的最佳范围是“视图”和吸气剂中的延迟数据加载:
RENDER_RESPONSE