2

I had problems when building a JSF project with ViewScope ManagedBeans. So I decided to isolate the problem to a simple code where obviously the problem persists. Basically I realized that the properties that are in the class TesteMBean work perfectly, however, the properties inherited from the superclass GenericoMBean not preserve its value.

I'm still beginner to it and so do not know if this is normal behavior of the JSF. Can someone enlighten me on this? and if possible tell me how to do it right through an example. thank you very much.

Following the code.

The SuperClass:

package br.com.telesnet.sige.web.mb;


public abstract class GenericoTesteMBean {

    protected String textoBase;

    public java.lang.String getTextoBase() {
        if (this.textoBase == null){
            return "";
        }else{
            return textoBase;
        }
    }

    public void setTextoBase(String textoBase) {
        this.textoBase = textoBase;
    }
}

The Inherited ManagedBean:

package br.com.telesnet.sige.web.testes;

import java.io.Serializable;

import javax.annotation.ManagedBean;
import javax.faces.bean.ViewScoped;

import br.com.telesnet.sige.web.mb.GenericoTesteMBean;

@ManagedBean
@ViewScoped
public class TesteMBean extends GenericoTesteMBean implements Serializable{
    private static final long serialVersionUID = 1L;
    private java.lang.Integer valor;
    private java.lang.String texto;

    public TesteMBean(){
        this.setValor(0);
    }

    public void incrementar(){
        this.setValor(this.getValor()+1);
        this.texto = this.getTexto() + "X";
        this.textoBase = this.getTextoBase() + "A";
    }

    public java.lang.Integer getValor() {
        if (this.valor == null){
            return 0;
        }else{
            return valor;
        }
    }

    public void setValor(java.lang.Integer valor) {
        this.valor = valor;
    }

    public java.lang.String getTexto() {
        if (this.texto == null){
            return "";
        }else{
            return texto;
        }
    }

    public void setTexto(java.lang.String texto) {
        this.texto = texto;
    }
}

The Web form:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:body>
    <f:view>
        <h:form id="formLabel">
            <h:outputLabel value="Valor:"></h:outputLabel>
            <h:outputLabel value="#{testeMBean.valor}"></h:outputLabel>

            <h:outputLabel value="Texto:"></h:outputLabel>
            <h:outputLabel value="#{testeMBean.texto}"></h:outputLabel>

            <h:outputLabel value="TextoBase:"></h:outputLabel>
            <h:outputLabel value="#{testeMBean.textoBase}"></h:outputLabel>

        </h:form>

        <h:form id="formIncremento">
            <h:commandButton actionListener="#{testeMBean.incrementar()}" value="incrementar">
            </h:commandButton>

        </h:form>


    </f:view>
</h:body>
</html>

The output undesired (Button "incrementar" clicked five times):

    Valor: 5 Texto: XXXXX TextoBase: A

The required output (Button "incrementar" clicked five times):

    Valor: 5 Texto: XXXXX TextoBase: AAAAA

3 Answers3

4

Just copied your three files to my workspace and "incrementar" works perfectly.

The only difference is on your managed bean, you have this import for @ManagedBean annotation

import javax.annotation.ManagedBean;

change it to

import javax.faces.bean.ManagedBean;

You may read this for the concepts Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean

Community
  • 1
  • 1
Serkan Arıkuşu
  • 5,549
  • 5
  • 33
  • 50
  • Thank you. I really need to read enough to understand these differences. I make the change in annotation for javax.faces.bean.ManagedBean, and even then the "A" does not increment "AAAAA ...". In your tests then this happened? What else could be causing this effect here? – Ronneery Teles Mar 19 '13 at 18:28
  • Other than that import everything was same and worked as designed. I would suggest using debug points on incremantar and methods in the abstract class. Try to use latest jars for jsf, and if possible use maven and start with an jsf archetype – Serkan Arıkuşu Mar 19 '13 at 19:17
1

Update
Removed my old answer now that I'm seeing your problem.

  1. You don't need a h:form around your h:outputLabels. Just use some kind of h:outputPanel around them, that's enough.
  2. You are using an actionListener in your h:commandButton instead of an action - that's ok in that case, but do you know the difference? In addition, you can remove the parenthesis inside the actionListener attribute.
  3. After that, try to use some debug messages in incrementar to help you find the problem.
  4. If you're using ajax functionality, you need to update the h:outputLabels inside your newly-created h:outputPanel.

So just:

<h:outputPanel id="myOutputPanel">
   ... your h:outputLabels here ...
</h:outputPanel>

<h:form id="formIncremento">
  <h:commandButton action="#{testeMBean.incrementar}" update=":myOutputPanel">
</h:form>

But the code provided does not use any ajax functionality. That means that the page has to be reloaded (refresh or F5 in your browser) in order to show the changes. That won't work well with a @ViewScopedbean as the bean gets destroyed after a page refresh and created immediately afterwards. either you should use an <f:ajax...> in your h:commandButtonor try to use some framework which has the functionality buildin, like primefaces' p:commandButton.

Community
  • 1
  • 1
Manuel
  • 3,828
  • 6
  • 33
  • 48
  • Thanks for the reply, but I still have some questions. I could not make it work applying their example. I tried to put the @ManagedProperty above the variable in the baseclass, then above a new created private variable with the same name in the derived class , using "#{testMBean.textoBase}" or "#{genericoTesteMBean.textoBase}" and still not saving the value. What can I do now? – Ronneery Teles Mar 19 '13 at 17:47
  • I added a bit more information in question, do not know if anything changes. thank you very much – Ronneery Teles Mar 19 '13 at 17:50
  • @RonneeryTeles I've updated my answer after seeing more of your code – Manuel Mar 20 '13 at 08:02
  • Is not the outputPanel a primefaces tag? I do not wish to add primefaces to the project yet... – Ronneery Teles Mar 20 '13 at 21:03
  • [JSF Tag Reference](http://www.jsftoolbox.com/documentation/help/12-TagReference/html/index.jsf). Take something you like (panelgrid, panelgroup). – Manuel Mar 21 '13 at 07:41
0

Your abstract base class must implement Serializable in order for the properties to get passed in requests.

Roost
  • 1