IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JSF Java Discussion :

Propriétés d'un bean mis à null lors de la validation


Sujet :

JSF Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 18
    Par défaut Propriétés d'un bean mis à null lors de la validation
    Bonjour à tous,

    Alors voila, je vais m'efforcer d'expliquer clairement mon problème.

    J'ai 2 pages JSF. Une qui affiche une liste de catégories et 1 qui permet d'en modifier 1.

    Une catégorie est définie par un id, un name et une description.

    Ma page de liste fonctionne très bien et redirige vers ma page de modification correctement par le biais de ce bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <p:commandButton ajax="false" action="#{NavigationBean.goDetailCategory}" icon="ui-icon-search" title="Voir la fiche">  
    					<f:setPropertyActionListener value="#{category}" target="#{CategoryDetailBean.category}" />  
    				</p:commandButton>
    Comme vous pouvez le voir, j'ai un bean CategoryDetailBean que j'ai défini dans le fichier faces-config comme suit :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <managed-bean>
    		<managed-bean-name>CategoryDetailBean</managed-bean-name>
    		<managed-bean-class>com.harsze.timetracer.bean.CategoryDetailBean</managed-bean-class>
    		<managed-bean-scope>request</managed-bean-scope>
    	</managed-bean>
    La page s'affiche correctement avec uniquement le nom et la description (l'id est utilisé pour la base de données.

    Le problème viens de la modification. J'ai une exception comme quoi l'id est null. En effet il l'est malgré qu'il soit bien défini. Cf les logs de mon projet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CategoryDetailBean - Appel du setter : 5
    CategoryDetailBean - Appel du getter : 5
    CategoryDetailBean - Appel du getter : 5
    CategoryDetailBean - Appel du getter : 5
    CategoryDetailBean - Appel du getter : null
    CategoryDetailBean - Appel du getter : null
    CategoryDetailBean - Appel du getter : null
    CategoryDetailBean - Appel du getter : null
    CategoryDetailBean - Appel du getter : null
    CategoryDetailBean - Appel du getter : null
    CategoryDetailBean - bla bla
    CategoryDetailBean - 
    CategoryDetailBean - COMMERCIALE
    Le premier setter interviens lors de la navigation (grâce au f:setPropertyActionListener. Les 3 getters sont appelés au chargement de ma page ==> Ils ont l'air corrects la valeur de l'id est bien récupérée...

    Par contre, dès que je clique pour valider, la boum, mon id repasse à null. Les autres valeurs sont ok.


    Voici ma page de détail :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <!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:c="http://java.sun.com/jsp/jstl/core"
    xmlns:p="http://primefaces.org/ui">
    <ui:composition>
    	<h:form>
    		<h3><h:outputText value="Modification d'une catégorie"/></h3>
     
    		<p:messages/>
     
    		<h:panelGrid columns="2" cellpadding="5px">	
    			<h:outputLabel value="Nom de la catégorie :" for="name"></h:outputLabel>  
                <p:inputText id="name" value="#{CategoryDetailBean.category.name}" required="true" requiredMessage="Vous devez entrer un nom pour la catégorie"/>  
     
                <h:outputLabel value="Description :" for="description"></h:outputLabel>  
                <p:editor id="description" value="#{CategoryDetailBean.category.description}" width="600"/> 
    		</h:panelGrid>
    		<br/>
    		<p:commandButton value="Valider" action="#{CategoryDetailBean.update}" ajax="false"/>
     
    	</h:form>
    </ui:composition>
    </html>
    et voici mon bean :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    package com.harsze.timetracer.bean;
     
    import java.io.Serializable;
     
    import javax.faces.context.ExternalContext;
    import javax.faces.context.FacesContext;
    import javax.servlet.http.HttpSession;
     
    import org.apache.log4j.Logger;
     
    import com.harsze.timetracer.entity.Category;
    import com.harsze.timetracer.model.functional.CategoriesModel;
    import com.harsze.timetracer.util.HarszeToolkit;
     
    public class CategoryDetailBean extends BaseBean implements Serializable{
     
    	/**
             * 
             */
    	private static final long serialVersionUID = -8684894588850123951L;
     
    	private Category	category;
     
    	public CategoryDetailBean()
    	{ 
    		logger = Logger.getLogger(CategoryDetailBean.class);
    	}
     
    	public void setCategory(Category category){
    		logger.debug("Appel du setter : "+category.getId());
    		this.category = category;
    	}
     
    	public Category getCategory(){
    		if (this.category == null)
    			this.category = new Category();
    		logger.debug("Appel du getter : "+this.category.getId());
    		return this.category;
    	}
     
    	public String update() throws Exception{	
     
    		logger.debug(this.category.getDescription());
    		logger.debug(this.category.getId());
    		logger.debug(this.category.getName());
    		CategoriesModel.UpdateCategory(this.category);
     
    		HarszeToolkit.FacesMessage("Catégorie modifiée avec succès.");
     
    		NavigationBean nb = (NavigationBean) HarszeToolkit.getBean("NavigationBean");
    		return nb.setRedirect("com_categories","list_categories");
    	}	
    }
    Donc pour solutionner le problème, je suis obligé de mettre mon id dans le page par exemple par ce bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    			<h:inputHidden value="#{CategoryDetailBean.category.id}"/>
    Mais je trouve ca illogique. La valeur de l'id est récupérer depuis le précédent bean et non modifiable alors je n'ai pas besoin de la mettre sur ma page.

    Qu'en pensez-vous ?

    Et merci pour les réponses :-)

    Lucas

  2. #2
    Membre Expert
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Par défaut
    en fait ta seconde page ne doit pas être en redirect (je le suppose car tu ne montres pas le fichier de navigation faces-config.xml)

    donc ton bean existe bien entre ta page 1 et ta page 2 parce qu'il font partie de la même "request" (puisque ton bean est aussi en request) et voilà pourquoi l'affichage se passe bien.

    en revanche, au second click, le request n'est plus du tout le même et donc un nouveau bean est instancié ... et du coup c'est null.

    Essaye avec ton bean en @ViewScoped, voire en @SessionScoped.

    enfin si tu es en JSF 2, tu peux utiliser les f:viewParam et f:metadata pour faire proprement ce genre de choses :
    http://mkblog.exadel.com/2010/07/lea...-page-actions/

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 18
    Par défaut
    Citation Envoyé par fxrobin Voir le message
    en fait ta seconde page ne doit pas être en redirect (je le suppose car tu ne montres pas le fichier de navigation faces-config.xml)

    donc ton bean existe bien entre ta page 1 et ta page 2 parce qu'il font partie de la même "request" (puisque ton bean est aussi en request) et voilà pourquoi l'affichage se passe bien.

    en revanche, au second click, le request n'est plus du tout le même et donc un nouveau bean est instancié ... et du coup c'est null.

    Essaye avec ton bean en @ViewScoped, voire en @SessionScoped.

    enfin si tu es en JSF 2, tu peux utiliser les f:viewParam et f:metadata pour faire proprement ce genre de choses :
    http://mkblog.exadel.com/2010/07/lea...-page-actions/
    Merci pour ces précisions.
    Je vous tiens au courant si ca marche.

  4. #4
    Membre Expert
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Par défaut
    ou encore, autre idée

    comme tu es en primefaces, utilise un p:dialog pour ouvrir une fenetre d'édition sur un lien de ton tableau, par exemple (ou un bouton) dans ton p:dialog il y a le form de mise à jour, une fois fermé, tu "update" le tableau avec AJAX et le tour est joué :-)

    si tu n'y arrives je posterai plus tard une petite démo de cela.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 18
    Par défaut
    euh alors effectivement je veux bien un exemple. Je suis assez novice en JSf de manière générale

    Juste pour compléter, mon bean de recherche est effectivement en request et l'autre aussi. Le passage entre les deux se fait par le biais d'un outcome (J'ai un NavigationBean. C'est assez compliqué mon truc finalement car j'ai un template a la joomla. Mon navigation bean stocke un composant et une view et grace a ca je passe tout sur une page unique (comme sur joomla) et je charge dynamiquement le contenu avec un ui-include de la sorte :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <div id="contentpanel">
    		<p:panel id="contentPanelTab" style="min-height:500px">
    			<ui:include src="/faces/components/#{NavigationBean.component}/#{NavigationBean.view}.xhtml"/>  
    		</p:panel>
    	</div>
    Bon je vais coucher la fille et je reviens :-)

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 18
    Par défaut
    Alors juste pour confirmer, j'ai passé mes beans en session (car bizarrement view ca ne marchait pas) et la c'est ok. Par contre, du coup c'est pas très bon....

    Aussi j'ai une question. J'ai déclaré mes beans dans le fichier faces-config.xml, j'ai vu des gens mettre les annotations @managedBean et @viewscooped, etc. au niveau de leur java. Alors quelle différence entre les 2 ? Dois je le faire dans les 2 fichiers ?? Je ne comprends pas tout là :-)

  7. #7
    Membre Expert
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Par défaut
    Citation Envoyé par fxrobin Voir le message
    ou encore, autre idée

    comme tu es en primefaces, utilise un p:dialog pour ouvrir une fenetre d'édition sur un lien de ton tableau, par exemple (ou un bouton) dans ton p:dialog il y a le form de mise à jour, une fois fermé, tu "update" le tableau avec AJAX et le tour est joué :-)

    si tu n'y arrives je posterai plus tard une petite démo de cela.

    comme prévu, voici donc un petit exemple.

    d'abord mon "modèle" : une classe Personne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    package model;
     
    public class Personne
    {
     
        private String nom;
        private String prenom;
     
        /**
         * @return the nom
         */
        public String getNom()
        {
            return nom;
        }
     
        /**
         * @param nom the nom to set
         */
        public void setNom(String nom)
        {
            this.nom = nom;
        }
     
        /**
         * @return the prenom
         */
        public String getPrenom()
        {
            return prenom;
        }
     
        /**
         * @param prenom the prenom to set
         */
        public void setPrenom(String prenom)
        {
            this.prenom = prenom;
        }
    }
    ensuite ma page index.xhtml :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    <?xml version='1.0' encoding='UTF-8' ?>
    <!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:h="http://java.sun.com/jsf/html"
          xmlns:p="http://primefaces.org/ui">
        <h:head>
            <title>Démonstration Dialog de modification en AJAX sur un tableau PrimeFaces</title>
        </h:head>
        <h:body>
            <h:form id="mainForm">
                <h:panelGrid columns="2">
                    Nom <h:inputText value="#{pageIndexBean.personne.nom}" />
                    Prénom <h:inputText value="#{pageIndexBean.personne.prenom}" />
                </h:panelGrid>
     
                <p:commandButton value="Ajouter" actionListener="#{pageIndexBean.ajouter()}"
                                 update="mainForm"/>
     
                <p:dataTable id="dataTableOutput" value="#{pageIndexBean.listePersonnes}" var="personne">
                    <p:column headerText="Nom">#{personne.nom}</p:column>
                    <p:column headerText="Prénom">#{personne.prenom}</p:column>
                    <p:column headerText="Action">
                        <p:commandButton value="Modifier" 
                                         process="@this"
                                         update=":dialogForm"
                                         oncomplete="dialogModification.show()"
                                         actionListener="#{pageIndexBean.selectionne(personne)}" />                                 
                    </p:column>
                </p:dataTable>
            </h:form>
     
            <h:form id="dialogForm">
                <p:dialog id="dialogModification" modal="true" widgetVar="dialogModification" height="500">
                    <h:panelGrid columns="2">
                        Nom <h:inputText value="#{pageIndexBean.selectionPersonne.nom}" />
                        Prénom <h:inputText value="#{pageIndexBean.selectionPersonne.prenom}" />
                    </h:panelGrid>
                    <p:commandButton value="Enregistrer" 
                                     process="dialogForm" 
                                     onclick="dialogModification.hide()" 
                                     update=":mainForm" />
                </p:dialog>
            </h:form>    
        </h:body>
    </html>
    et enfin le ManagedBean en scope view :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    package beans;
     
    import java.util.ArrayList;
    import java.util.List;
    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    import model.Personne;
     
    @ManagedBean
    @ViewScoped
    public class PageIndexBean
    {
     
        private Personne nouvellePersonne;
        private List<Personne> listePersonnes;
        private Personne selectionPersonne;
     
        @PostConstruct
        public void init()
        {
            nouvellePersonne = new Personne();
            selectionPersonne = new Personne();
            listePersonnes = new ArrayList<Personne>();
        }
     
        public void ajouter()
        {
            listePersonnes.add(nouvellePersonne);
            nouvellePersonne = new Personne();
        }
     
        /**
         * @return the personne
         */
        public Personne getPersonne()
        {
            return nouvellePersonne;
        }
     
        /**
         * @param personne the personne to set
         */
        public void setPersonne(Personne personne)
        {
            this.nouvellePersonne = personne;
        }
     
        /**
         * @return the listePersonnes
         */
        public List<Personne> getListePersonnes()
        {
            return listePersonnes;
        }
     
        /**
         * @param listePersonnes the listePersonnes to set
         */
        public void setListePersonnes(List<Personne> listePersonnes)
        {
            this.listePersonnes = listePersonnes;
        }
     
        /**
         * @return the selectedPersonne
         */
        public Personne getSelectionPersonne()
        {
            return selectionPersonne;
        }
     
        /**
         * @param selectedPersonne the selectedPersonne to set
         */
        public void setSelectionPersonne(Personne selectedPersonne)
        {
            this.selectionPersonne = selectedPersonne;
        }
     
        public void selectionne(Personne p)
        {
            this.selectionPersonne = p;
        }
    }

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 18
    Par défaut
    Bonjour et merci pour ce exemple.

    Il y a un truc que je n'ai pas encore l'habitude d'utiliser c'est le update. Il fait mon truc a l'ancienne. Quand je clique pour modifier, je change de page (fiche modif etc...) Il faut que je me ré habitue aux principes du JSF.

    Sinon si tu as un avis sur mon archi MVC, je suis preneur :-)

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/02/2007, 10h06
  2. Count sur une propriété d'un bean entité
    Par dmetzler dans le forum JSF
    Réponses: 11
    Dernier message: 14/02/2007, 21h35
  3. Valeur null lors de la lecture apres un insert
    Par omlip dans le forum Hibernate
    Réponses: 1
    Dernier message: 07/07/2006, 13h56
  4. Réponses: 2
    Dernier message: 30/05/2006, 09h02
  5. Réponses: 6
    Dernier message: 17/06/2005, 14h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo