1

I have a grid with a list of objects and I am trying to create a basic CRUD. Updates and deletes are going quite fine and without any problems, however, when I try to perform a edit on the selected object the setPropertyActionListener that I've set isn't performing as expected. I've searched on several threads but no success.

Here goes my code:

On my crud-aplicacoes.html I gotta a grid and this is the code of my button where I set my setPropertyActionListener and also my action which goes to action ="editar-aplicacao" that is another page. I'm getting my property aplicacaoSelecionada always null.

<p:commandButton icon="ui-icon-pencil"
                        title="#{msg['label.button.editar']}" action="editar-aplicacao"
                        actionListener="#{aplicacoesMB.editarAplicacao}">
                        <f:setPropertyActionListener
                            target="#{aplicacoesMB.aplicacaoSelecionada}" value="#{app}" />

                    </p:commandButton>

My managed bean:

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;

import org.primefaces.model.DualListModel;

import br.com.cnen.enums.SituacaoAplicacaoeEnum;
import br.com.cnen.vo.AplicacaoVO;
import br.com.cnen.vo.PerfilVO;
import br.com.cnen.web.facade.AplicacoesFacade;

@RequestScoped
@ManagedBean(name = "aplicacoesMB")
public class AplicacoesMB extends BeanAbstract {


    private static final long serialVersionUID = 1L;

    private List<AplicacaoVO> listaAplicacoes;

    private AplicacaoVO aplicacaoSelecionada;

    private PerfilVO perfilSelecionado;

    private boolean edicaoExibicao;

    @Inject
    private AplicacoesFacade facadeAplicacao;

    private List<PerfilVO> source;
    private List<PerfilVO> target;
    private DualListModel<PerfilVO> dualListPerfil;

    @PostConstruct
    public void carregarAplicacoes() {
        listaAplicacoes = facadeAplicacao.listarTodos();
        this.edicaoExibicao = false;
        dualListPerfil = new DualListModel<PerfilVO>();
    }

    public List<PerfilVO> perfis() {
        return facadeAplicacao.carregarComboPerfis();
    }

    public List<SituacaoAplicacaoeEnum> comboStatus() {
        List<SituacaoAplicacaoeEnum> lista = new ArrayList<SituacaoAplicacaoeEnum>();
        for (SituacaoAplicacaoeEnum current : SituacaoAplicacaoeEnum.values()) {
            lista.add(current);
        }
        return lista;
    }

    public String editarAplicacao() {
        this.edicaoExibicao = false;
        pickList();
        return "editar-aplicacao";
    }

    public String visualizarAplicacao() {
        this.edicaoExibicao = true;
        return "editar-aplicacao";
    }

    public void excluirAplicacao() {
        facadeAplicacao.remover(this.aplicacaoSelecionada);
        this.carregarAplicacoes();
        this.addMensagem("A exclusão foi realizada com sucesso.", FacesMessage.SEVERITY_INFO);
    }

    public void bloquearAplicacao() {
        this.aplicacaoSelecionada.setSituacao(SituacaoAplicacaoeEnum.BLOQUEADO);
        facadeAplicacao.bloquear(this.aplicacaoSelecionada);
        this.addMensagem("O bloqueio foi realizado com sucesso!", FacesMessage.SEVERITY_INFO);
    }

    public void desbloquearAplicacao() {
        this.aplicacaoSelecionada
                .setSituacao(SituacaoAplicacaoeEnum.DESBLOQUEADO);
        facadeAplicacao.desbloquear(this.aplicacaoSelecionada);
        this.addMensagem("O desbloqueio com sucesso!", FacesMessage.SEVERITY_INFO);
    }

    public void alterarAplicacao(){
        facadeAplicacao.alterar(aplicacaoSelecionada);
        this.addMensagem("O atualização foi realizada com sucesso!", FacesMessage.SEVERITY_INFO);
    }

    public void addPerfil(){

    }

    public void pickList(){
        source = facadeAplicacao.carregarComboPerfis();
        target = new ArrayList<PerfilVO>();

        if(aplicacaoSelecionada!=null)
            target = aplicacaoSelecionada.getListaPerfis();
        dualListPerfil = new DualListModel<PerfilVO>(source, target);
    }

    /**
     * 
     * Getts and setters
     * 
     */
    public List<AplicacaoVO> getListaAplicacoes() {
        return listaAplicacoes;
    }

    public AplicacaoVO getAplicacaoSelecionada() {
        return aplicacaoSelecionada;
    }

    public void setAplicacaoSelecionada(AplicacaoVO aplicacaoSelecionada) {
        this.aplicacaoSelecionada = aplicacaoSelecionada;
        System.out.println("-> "+ aplicacaoSelecionada.getAplicaoId());
    }

    public PerfilVO getPerfilSelecionado() {
        return perfilSelecionado;
    }

    public void setPerfilSelecionado(PerfilVO perfilSelecionado) {
        this.perfilSelecionado = perfilSelecionado;
    }

    public boolean isEdicaoExibicao() {
        return edicaoExibicao;
    }

    public List<PerfilVO> getSource() {
        return source;
    }

    public void setSource(List<PerfilVO> source) {
        this.source = source;
    }

    public List<PerfilVO> getTarget() {
        return target;
    }

    public void setTarget(List<PerfilVO> target) {
        this.target = target;
    }

    public DualListModel<PerfilVO> getDualListPerfil() {
        return dualListPerfil;
    }

    public void setDualListPerfil(DualListModel<PerfilVO> dualListPerfil) {
        this.dualListPerfil = dualListPerfil;
    }


}

On my editarAplicacao() I can't access the property because it is always going null. Any thoughts on this issue?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
pedroct92
  • 404
  • 1
  • 4
  • 18

2 Answers2

3

Your concrete problem is caused by (ab)using actionListener instead of action to perform a business action. All actionListeners are invoked in the very same order as they have been attached on the component and then finally the action is invoked.

In other words, the <f:setPropertyActionListener> is in your particular case invoked after #{aplicacoesMB.editarAplicacao}, which totally explains the symptom you're seeing of the property not being set.

Fix actionListener to be action.

action="#{aplicacoesMB.editarAplicacao}"

Additionally, you can also get rid of <f:propertyActionListener> altogether and pass the property as action method argument.

action="#{aplicacoesMB.editarAplicacao(app)}"

with

public String editarAplicacao(AplicacaoVO aplicacaoSelecionada) {
    // ...
}

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BalusC for the quick reply and also the explanation. Both solutions work, however, this one is, in my point of view, clearer and closer of what I wanted. – pedroct92 Mar 06 '15 at 16:43
0

You can replace

<f:setPropertyActionListener
                            target="#{aplicacoesMB.aplicacaoSelecionada}" value="#{app}" />

with

<f:attribute name="aplicacao" value="#{app}"></f:attribute>

and in your actionListenerMethod getting the attribute :

this.aplicacaoSelecionada = ((AplicacaoVO) event.getComponent().getAttributes().get("aplicacao"));

Luca
  • 1
  • 2
  • Finally, it works as I needed tough any thoughts why I was facing this issue with `setPropertyActionListener` ? thanks a lot! – pedroct92 Mar 06 '15 at 13:29
  • 2
    Poor answer. This does nowhere explain how and why exactly OP's attempt failed, hereby leaving the OP (and other future readers stumbling upon the same problem via search) in all cluelessness as to the actual cause and thus actually learn nothing. – BalusC Mar 06 '15 at 13:41