I have a quite complicated request scoped JSF 1.2 managed bean with various methods and properties. Some of the properties are mapped to URL request parameters so that it can populate an entity object according to the id attribute in the URL.
I use the same managed bean both to create a new record for that entity using one jsf page, and another one for updating a couple of fields. In create mode, there are no url parameters, and submitting the form using an specifying an action method just does what it's told and executes the method.
But when in update mode, getting the entity's id from the request parameter (in the URL) which populates the form perfectly with the entity data pulled from the database, the submit button i.e. the does not invoke the action method on the same managed bean, but reloads the page with the url parameters gone and with the form blank this time since there's no id in the url, the id property which is used when referring to the corresponding data by a service class method to set the entity object is null.
So how would I get that method executed in this update-mode as I call it?
Listening to an advice, I had also included hidden fields which contain the values of id parameters obtained from the URL in the update form, which didn't seem to work.
Here's the code fragment containing the form in the problematic JSF page:
<h:form id="ostOnayForm">
<h:messages style="color:red" />
<h:inputHidden value="#{oduncStokTalepBean.viewID}" />
<h:inputHidden value="#{oduncStokTalepBean.adimID}" />
<h:panelGrid id="oracleERP" columns="3"
rendered="#{oduncStokTalepBean.aksiyon.faz==3}">
Personel ödünç cari kodu:
<h:inputText id="carikod" value="#{oduncStokTalepBean.oduncCariKod}"
required="true"
requiredMessage="Bu personelin 'ödünç cari kodu'nu girmelisiniz. (Eğer böyle bir kod tanımlı değilse, önce tanımı yapılmalıdır."
validatorMessage="Bu alana en fazla 25 karakter girebilirsiniz.">
<f:validateLength maximum="25" />
</h:inputText>
<h:message for="carikod" style="color:red" />
</h:panelGrid>
<h:panelGroup id="depocu1"
rendered="#{oduncStokTalepBean.aksiyon.faz==2}">
Personel ödünç cari kodu:
<h:inputText value="#{oduncStokTalepBean.oduncCariKod}"
required="false"
validatorMessage="Bu alana en fazla 25 karakter girebilirsiniz.">
<f:validateLength maximum="25" />
</h:inputText>
</h:panelGroup>
<h:panelGroup id="depocu2"
rendered="#{oduncStokTalepBean.aksiyon.faz==2}">
<h:selectBooleanCheckbox value="#{oduncStokTalepBean.kargoyla}" />Ürün kargo firması ile teslim edilecek
</h:panelGroup>
<h:panelGrid columns="3"
rendered="#{oduncStokTalepBean.onaylamaYetkisi}">
Görüşler:
<h:inputTextarea id="gorus" value="#{oduncStokTalepBean.gorus}"
required="true"
validatorMessage="Bu alana en fazla 255 karakter girebilirsiniz."
requiredMessage="Lütfen görüş de bildirin.">
<f:validateLength maximum="255" />
</h:inputTextarea>
<h:message for="gorus" style="color:red" />
<h:commandButton action="#{oduncStokTalepBean.vazgec}" value="Vazgeç" />
<h:commandButton type="submit" action="#{oduncStokTalepBean.onayla}"
value="Onayla" rendered="#{oduncStokTalepBean.onaylamaYetkisi}" />
<h:commandButton action="#{oduncStokTalepBean.reddet}"
value="Reddet"
onclick="return confirm('Bu formu reddetmek istediğinizden emin misiniz?')"
rendered="#{oduncStokTalepBean.onaylamaYetkisi}" />
</h:panelGrid>
</h:form>
The backing bean:
public class OduncStokTalepBean extends SurecBean {
private String oduncCariKod;
private Boolean kargoyla;
private OduncStokTalep oduncStokTalep = new OduncStokTalep("ost", "Ödünç Stok Talebi");
private List<SelectItem> depoListesi = new ArrayList<SelectItem>();
private OduncStokAdres osa = new OduncStokAdres();
private OduncStokAdresJpaController osaServ = new OduncStokAdresJpaController();
public OduncStokTalepBean() {
super();
}
@PostConstruct
public void initializeOST() {
if (FacesUtil.getSessionAttribute("GO_Person_id") != null ) {
GO_Person_id = Integer.valueOf((String) FacesUtil.getSessionAttribute("GO_Person_id"));
if (viewID != null) {
System.out.println("ostBean got viewID:"+viewID);
this.oduncStokTalep = ostServ.findOduncStokTalep(viewID);
this.editModu = true;
this.oduncCariKod = this.oduncStokTalep.getPersonelOduncCariKodu();
this.kargoyla = this.oduncStokTalep.getKargoylaTeslim();
System.out.println("ost: "+oduncStokTalep.getId()+" * "+oduncStokTalep.toString());
if (adimID != null) {
this.aksiyon = aServ.findAkisAdim(adimID);
this.setAksiyonModu(true);
} else {
System.out.println("adimID was null, reading it from Surec...");
if (oduncStokTalep.getPendingAction()!=null) {
this.aksiyon = aServ.findAkisAdim(oduncStokTalep.getPendingAction());
System.out.println("Found :"+aksiyon.getId()+" "+aksiyon.getAktor()+aksiyon.getAdimTanim());
this.setAksiyonModu(true);
} else {
System.out.println("oduncStokTalep.getPendingAction() seems also null :"+oduncStokTalep.getPendingAction());
this.setAksiyonModu(false);
开发者_如何学Python }
}
if (editModu && GO_Person_id!=null) {
if (oduncStokTalep.getSuAnKimde().contains(GO_Person_id.toString()) )
this.onaylamaYetkisi = true;
if (this.aksiyon != null && this.aksiyon.getAktor().contains(GO_Person_id.toString()))
this.onaylamaYetkisi = true;
}
} else {
System.out.println("viewID is null.");
System.out.println("initializing OST...");
this.editModu = false;
this.setAksiyonModu(false);
oduncStokTalep.setPersonId(GO_Person_id);
}
} else oturumActirt();
}
// THE FOLLOWING METHOD IS EXECUTED PERFCETLY WITH A BLANK FORM AND WITH NO GET PARAMETER
public String kaydet(){
Long formId;
System.out.println("invoking ost kaydet()...");
ostServ.doPersist(oduncStokTalep);
formId = oduncStokTalep.getId();
System.out.println("OST MB obtained Id:"+formId);
if (formId != null) {
doSomeOtherStuff();
}
FacesUtil.setSessionAttribute("surecView", null);
FacesUtil.setSessionAttribute("surecAdim", null);
FacesUtil.setSessionAttribute("surecID", null);
FacesContext fc = FacesUtil.getFacesContext();
fc.addMessage(null, new FacesMessage("Ödünç Stok talebiniz başarıyla oluşturuldu ve "+formId+" no'lu ile sisteme kaydedildi."));
oduncStokTalep = new OduncStokTalep("ost", "Ödünç Stok Talebi");
return "KAYDETVEGONDER";
}
// This method is never even called form the update form :(((((
public String onayla() throws NonexistentEntityException, Exception {
System.out.println("Onayla() invoked for OST "+oduncStokTalep.getId());
if (this.onaylamaYetkisi) {
System.out.println("onaylama yetkisi de var.");
SomeActionController ac1 = new SomeActionController();
if (aksiyon == null)
aksiyon = ac1.getPendingAction("ost", this.viewID, String.valueOf(this.GO_Person_id));
ac1.adimiTamamla(this.GO_Person_id, "ost", this.viewID, aksiyon.getId(), true, this.gorus);
}
oduncStokTalep = new OduncStokTalep("ost", "Ödünç Stok Talebi");
return "DASHBOARD";
}
// Neither this one via <h:commandButton action="#{oduncStokTalepBean.test}" value="Test Action Method" />
public void test() {
System.out.println("Test OK");
}
// getters and setters, etc.
}
and the faces-config fragment:
<managed-bean>
<managed-bean-name>surecBean</managed-bean-name>
<managed-bean-class>net.ozar.wf.jsfmanaged.SurecBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>viewID</property-name>
<property-class>java.lang.Long</property-class>
<value>#{param.id}</value>
</managed-property>
<managed-property>
<property-name>adimID</property-name>
<property-class>java.lang.Long</property-class>
<value>#{param.aid}</value>
</managed-property>
<managed-property>
<property-name>surecID</property-name>
<property-class>java.lang.String</property-class>
<value>#{param.sid}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>oduncStokTalepBean</managed-bean-name>
<managed-bean-class>net.ozar.wf.jsfmanaged.OduncStokTalepBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>viewID</property-name>
<property-class>java.lang.Long</property-class>
<value>#{param.id}</value>
</managed-property>
<managed-property>
<property-name>adimID</property-name>
<property-class>java.lang.Long</property-class>
<value>#{param.aid}</value>
</managed-property>
</managed-bean>
You're using the rendered
attribute to toggle the visibility of the components. When using this with a request scoped bean, you need to ensure that the same condition for the rendered
attributes is been evaluated during processing the form submit as it was during displaying the form. When the condition of the rendered
attribute of the button or one of its parent components evaluates false
, then JSF won't invoke the button.
If you cannot ensure that the same condition can be preserved during bean's (post)construction, then you need to put the bean in the view scope (JSF 2.0 only) or to use Tomahawk's <t:saveState>
to retain the bean in the subsequent request.
See also:
- How to call an action method of a UICommand Component which was rendered conditionally?
- JSF 1.2: How to keep request scoped managed bean alive across postbacks on same view?
Check if there is an error being generated on any setter of your components.
精彩评论