« Blogbuster How-to samples are up | Main | ADF Faces: Pre-select checkboxes based on selected LOV options »
ADF Faces Rich Client: What if managed beans are going wild
By frank.nimphius | October 17, 2007
A question on OTN reported that the managed bean method used to populate a list was called twice. While many applications silently live with a bean called twice, in specific usecases having a method executed twice is just too expensive. So bug or feature ? Actually none of the two. The JSF request lifecycle uses a postback call, which means that the page - in this case the page with the list on it - is called when a new list value gets selected (using autosubmit = true) to handle the model update.
Though this question came up for JDeveloper 11 and ADF Faces RC, its the same for JDeveloper 10.1.3 and ADF Faces DHTML.
-
<?xml version='1.0' encoding='windows-1252'?>
-
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
-
xmlns:h="http://java.sun.com/jsf/html"
-
xmlns:f="http://java.sun.com/jsf/core"
-
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
-
<jsp
utput omit-xml-declaration="true" doctype-root-element="HTML" -
doctype-system="http://www.w3.org/TR/html4/loose.dtd"
-
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
-
<jsp:directive.page contentType="text/html;charset=windows-1252"/>
-
<f:view>
-
<af:document>
-
<af:form>
-
<af:selectOneChoice label="Label 1" autoSubmit="true" immediate="true">
-
<f:selectItems value="#{temp.createList}" />
-
</af:selectOneChoice>
-
</af:form>
-
</af:document>
-
</f:view>
-
</jsp:root>
The managed bean code referenced by the listbox looks as follows
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import javax.faces.model.SelectItem;
-
-
public class Temp {
-
public Temp() {
-
}
-
-
public List<SelectItem> getCreateList() {
-
-
List<SelectItem> selectItemList = new ArrayList<SelectItem>();
-
SelectItem selectItem = new SelectItem();
-
selectItem.setLabel("item 1");
-
selectItem.setValue("item 1");
-
selectItemList.add(selectItem);
-
-
return selectItemList;
-
}
-
}
To track the issue, I wrote a PhaseListener, just to see in which phase the managed bean - which allegedly was called twice - is called. The printout of this listener was
07/10/17 03:56:39 Before - RESTORE_VIEW 1
07/10/17 03:56:39 After - RESTORE_VIEW 1
07/10/17 03:56:39 Before - APPLY_REQUEST_VALUES 2
07/10/17 03:56:39 I am instantiated
07/10/17 03:56:39 Creating List
07/10/17 03:56:39 After - APPLY_REQUEST_VALUES 2
07/10/17 03:56:39 Before - PROCESS_VALIDATIONS 3
07/10/17 03:56:39 After - PROCESS_VALIDATIONS 3
07/10/17 03:56:39 Before - UPDATE_MODEL_VALUES 4
07/10/17 03:56:39 After - UPDATE_MODEL_VALUES 4
07/10/17 03:56:39 Before - INVOKE_APPLICATION 5
07/10/17 03:56:39 After - INVOKE_APPLICATION 5
07/10/17 03:56:39 Before - RENDER_RESPONSE 6
07/10/17 03:56:39 Creating List
07/10/17 03:56:39 After - RENDER_RESPONSE 6
Obviously the managed bean is called twice, but in two different phases of the lifecycle. To prevent the managed bean method to be called twice, you need to handle the postback case, which you can do with ADF Faces. So in this case, changing the managed bean code to
-
public List<SelectItem> getCreateList() {
-
List<SelectItem> selectItemList = new ArrayList<SelectItem>();
-
if (!AdfFacesContext.getCurrentInstance().isPostback()) {
-
-
SelectItem selectItem = new SelectItem();
-
selectItem.setLabel("item 1");
-
selectItem.setValue("item 1");
-
selectItemList.add(selectItem);
-
}
-
-
return selectItemList;
-
}
solves the issue.
07/10/17 04:01:00 After - APPLY_REQUEST_VALUES 2
07/10/17 04:01:00 Before - PROCESS_VALIDATIONS 3
07/10/17 04:01:00 After - PROCESS_VALIDATIONS 3
07/10/17 04:01:00 Before - UPDATE_MODEL_VALUES 4
07/10/17 04:01:00 After - UPDATE_MODEL_VALUES 4
07/10/17 04:01:00 Before - INVOKE_APPLICATION 5
07/10/17 04:01:00 After - INVOKE_APPLICATION 5
07/10/17 04:01:00 Before - RENDER_RESPONSE 6
07/10/17 04:01:00 Creating List
07/10/17 04:01:00 After - RENDER_RESPONSE 6
Frank
Topics: ADF Faces RC | No Comments »
Comments are closed.
