I have a conversation-scoped SFSB backing bean with the following business methods:
@End public void applyData(){ ... em.flush(); }
@Factory(value="totalUndefined", scope=ScopeType.EVENT) public Long getTotalUndefined(){ Long totalUndefined = (Long)entityManager.createQuery("select count(*) "+ " from RecoveredEquipmentManagement rem "+ " where rem.recoveryType = ( SELECT lv.listValueId "+ " FROM ListValue lv, List l "+ " WHERE l.listId = lv.list.listId "+ " and l.listName = :recoveryType"+ " and lv.listValue = :undefined)") .setParameter("recoveryType", RECOVERY_TYPE) .setParameter("undefined", UNDEFINED) .getSingleResult(); return totalUndefined; }
The problem is that the following xhtml fragment is not being refreshed in time (in my test case, total number is expected to decrement by one):
<a4j:outputPanel ajaxRendered="true"> <h:panelGrid columns="2" rendered="#{totalUndefined gt 0 and recoveredEquipmentManagementList.getRowCount() > 0}"> <s:graphicImage value="/img/warning_red_lg.jpg"/> <h:outputText value="There are #{totalUndefined} undefined item number(s)."/> </h:panelGrid> </a4j:outputPanel>
The @Factory method is executing before the applyData action-handler method for my a4j:commandButton. Thus, the decremented value is not displayed in the JSF page.
How can I reverse the order of execution while still using @Factory pattern? Alternatively, I could probably just simply call the public method directly and remove the @Factory annotation. Ideally, I only wan that method to be executed once per HTTP rep/resp cycle (that's why it's EVENT scoped).
Also, I noticed in the debugger that the @Factory method is executing twice (at least in some cases) and there is a JPQL query in that method. How best to handle that to avoid duplicate SQL executions in the same HTTP req/resp cycle? Perhaps I can make the local variable an instance variable instead and check for null?