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 :

datatable, fonctionnement etrange


Sujet :

JSF Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de koack
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 60
    Par défaut datatable, fonctionnement etrange
    Bonjour,

    j'utilise une datatable pour afficher divers données mais j'ai remarqué que la datatable faisait plusieurs fois appel au getter pour obtenir la liste a afficher.

    ma jsp : j'ai supprimé ce qui ne me paraisait pas utile

    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
    <%--BODY--%>
        <div id="body">
               
        <h:dataTable id="Account" width="100%" value="#{AccountManagedBean.accountEntityList}" var="uneLigne" rules="rows" >
        <h:column>
         	<f:facet name="header">
            	<h:outputText value="numero de compte"/>
            </f:facet>
            <h:form>
            <h:commandLink action="#{AccountManagedBean.showDetails}">
            <h:outputText value="#{uneLigne.account}"/>
            </h:commandLink>
            </h:form>
        </h:column>
        <h:column>
         	<f:facet name="header">
            	<h:outputText value="description"/>
            </f:facet>
            <h:outputText value="#{uneLigne.description}"/>
        </h:column>
      	</h:dataTable>
        </div>
    </body>
    Losque j'affiche ma jsp j'ai deja fais 3 appels au getter de la liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    10:49:42,484 INFO  [STDOUT] UserAccountsBean constructor
    10:49:42,484 INFO  [STDOUT] getAccountEntityList
    10:49:42,505 INFO  [STDOUT] getAccountEntityList
    10:49:42,515 INFO  [STDOUT] getAccountEntityList
    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
    @Stateful
    public class UserAccountsBean implements UserAccountsBeanLocal {
    
           
    	@PersistenceContext(unitName ="Mes_Tables")
    	private EntityManager em;
    	private UserAccountsEntity userAccountsEntity = new UserAccountsEntity(); 
    	
    	public UserAccountsBean() {
    		System.out.println("UserAccountsBean constructor");
    	}
    	
    	public void populate(){
    						
    	ici je rempli ma base pour les tests	
    	}
    	public UserAccountsEntity getUserAccountEntity(String login){
    		
    		Query query = em.createQuery("SELECT a FROM UserAccountsEntity a WHERE a.login=:login");
    		query.setParameter("login", login);
    		int a=0;		
    		try {
    			//TODO single result
    			userAccountsEntity=(UserAccountsEntity)query.getResultList().get(0); //.getSingleResult();
    			a=userAccountsEntity.getAccountsEntity().size();
    		}
    		
    		catch (NoResultException nre){
    			
    		}
    				
    		
    		return userAccountsEntity;
    	}
    	}
    et mon managedbean :

    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
     
     
    public class AccountManagedBean {
     
    	@EJB
    	private UserAccountsBeanLocal userAccountsBean;
     
    	private UserAccountsEntity userAccountsEntity = new UserAccountsEntity();
    	private final Principal user;
     
     
    	public AccountManagedBean() {
    	/*Save the principal's user*/	
    	FacesContext fc = FacesContext.getCurrentInstance();
    	user = fc.getExternalContext().getUserPrincipal();	
     
    	}
     
    	public String showDetails() {
    		System.out.println("showDetails");
    		FacesContext fc = FacesContext.getCurrentInstance();
    		HtmlDataTable selectedAccount = (HtmlDataTable) fc.getViewRoot().findComponent("Account");
    		AccountEntity account = (AccountEntity)selectedAccount.getRowData();
     
    		if(account!=null) {
    			System.out.println("selected account ="+account.getId());
    		}
     
    		return "showDetails";
    	}
     
    	public List<AccountEntity> getAccountEntityList() {
    		System.out.println("getAccountEntityList");
    		userAccountsBean.populate();
    		userAccountsEntity = userAccountsBean.getUserAccountEntity(user.getName());
    		List<AccountEntity> maliste = new ArrayList<AccountEntity>();
    		maliste= userAccountsEntity.getAccountsEntity();
    		return maliste;
     
    	}
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    }
    Et lorsque je fais appel a showDetails, la c'est le ponpon je fais au moins 15 appels au getter de la liste.

    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
     
    11:05:15,663 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,673 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,685 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,693 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,702 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,709 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,715 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,715 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,725 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,735 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,745 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,755 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,765 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,775 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,785 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,785 INFO  [STDOUT] showDetails
     
    11:05:15,785 INFO  [STDOUT] selected account =3
     
    11:05:15,805 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,805 INFO  [STDOUT] getAccountEntityList
     
    11:05:15,825 INFO  [STDOUT] getAccountEntityList
    est ce normal ???

  2. #2
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    En fait il ne s'agit pas d'un comportement étrange, les getters sont effectivement appelés plusieurs fois (savoir si 3 ou 15 fois est normal ou pas, ça reste à voir).
    Cela vient du fonctionnement même de JSF, qui a parfois besoin de récupérer une donnée (via le getter) à différents moments du cycle de vie de la requête JSF.

    Cela ne devrait normalement pas poser trop de problème à condition que tes getters soient de simples méthodes retournant une valeur / un objet. Initialiser des éléments(*), ou pire, faire du code métier dans un getter est forcément une mauvaise chose !

    Initialiser des propriétés peut se faire dans d'autres endroits que le getter, par exemple :

    • le constructeur du bean ;
    • des blocs static dans ta classe ;
    • à l'initialisation du bean (si tu utilises par exemple l'annotation @PostConstruct) ;
    • pendant un événement (une action Java lancée par un action / actionListener)



    (*) cela peut être acceptable dans certains cas, par exemple pour initialiser une liste d'objets de référence, de préférence avec un scope du bean différent de request. On aura alors un test qui vérifiera si la liste est déjà initialisée ou pas. Cela donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    private List<SelectItem> countries = null;
     
    public List<SelectItem> getCountries() {
        if (countries == null) {
            countries = new ArrayList<SelectItem>();
            countries.add(new SelectItem("FR", "France"));
            ...
        }
        return countries;
    }
    Dans cet exemple, la liste est initialisée au premier appel du getter, les autres appels ne faisant alors que retourner la liste déjà remplie.
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  3. #3
    Membre confirmé Avatar de koack
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 60
    Par défaut
    merci pour la reponse tres rapide, c'est vrai que mon getter est un peu fait a la va vite, voir meme horrible :p

    Mais j'etais pressé de tester ma datatable. Je vais corriger tout ca.

    Mais j'aurai encore une derniere question (je laisse de côté le nombre d'appel)pourquoi JSF fait appel au getter de la liste sur la methode showDetails de mon managedbean alors que j'ai testé avec ce code:
    Il n'y a aucun rapport entre une liste de la datatable et un h:commandLink


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ....
    public String showDetails {
       return null;
    ....
    }

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    D'abord, tout le formulaire va être exploré, ainsi que la datatable et le action, lors de la phase "applyrequestvalue". C'est dans cette phase que les inputs de la datatable seront remplie et que l'action visée sera enregistrée. Pour info, votre navigateur va envoyer, entre autres, à JSF: form1:Account:2:_idjsf31

    avec "2" le numéro de la ligne où vous avez cliqué, et _idjsf31 l'id autogénéré pour votre action puisque vous n'en avez pas spécifié.

    Ensuite, on va de nouveau tout parcourir dans la phase de validation et de correction
    Enfin, si la validation est ok, l'action visée sera appelée
    Un nouveau rendu sera effectué.

    Donc, oui, il est normal que la datatable soit parcourue plusieurs fois. Et chaque parcours implique 1 getter sur la value + 1 ou plusieurs getter / ligne

  5. #5
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Qu'entends tu par "cela n'a aucun rapport" ?

    De toutes façons, ton commandLink va générer une requête HTTP, et comme il n'y a pas de navigation (i.e. l'utilisateur va rester sur la même page), JSF va devoir recréer toute la page. JSF devra donc regénérer l'intégralité de ton tableau, y compris les valeurs qui y sont contenues. Donc il faudra que JSF accède à ta liste de données, via le getter.

    De plus, ton commandLink se situe dans le tableau. Or le datatable dispose de fonctionnalité avancée pour savoir sur quelle ligne du tableau (donc quel élément lié dans ta liste de données) cette action a été faite (voir le getRowData() des tableaux). Cela devrait expliquer quelques appels supplémentaires...
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  6. #6
    Membre confirmé Avatar de koack
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 60
    Par défaut
    Merci pour vos réponses je comprend un peu mieux pourquoi tout ces appels sur le getter.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonctionnement incomprehensif du dataTable
    Par DevServlet dans le forum JSF
    Réponses: 10
    Dernier message: 07/08/2009, 18h03
  2. fonctionnement etrange de readdir
    Par badoumba dans le forum Langage
    Réponses: 2
    Dernier message: 09/10/2008, 14h46
  3. datatable rendered ne fonctionne pas
    Par ang.net dans le forum JSF
    Réponses: 1
    Dernier message: 07/07/2008, 20h10
  4. fonctionnement du composant dataTable
    Par hibao dans le forum JSF
    Réponses: 3
    Dernier message: 02/07/2008, 09h15
  5. Réponses: 1
    Dernier message: 03/08/2007, 16h42

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