Bonjour.

Je suis débutant en Java EE. Et voilà que je tombe sur un os depuis quelques jours que je ne parviens pas à résoudre donc je fais appel à votre expérience.

J'ai une application web (IDE Netbeans, Serveur applications: Glassfish) qui est sensé chercher des marques de composants/ordinateurs dans une DB et qui affiche le résultat sous forme de DataTable à l'utilisateur. Sur chaque ligne de la DataTable il y a un lien qui permet d'afficher le "détail de la marque" (et de modifier son nom si besoin mais je n'ai pas encore implémenté cette partie dans mon code mais là n'est pas le problème). Au dessus de cette DataTable, il y a un champ de recherche qui permet de de filtrer la base de données sur la base des caractères rentrés. Cette recherche me donne une nouvelle DataTable. Là, ça fonctionne toujours. Mais là où est le hic, c'est quand que clique sur une des lignes de cette nouvelle DataTable. La page xhtml générée contient la DataTable de base (toutes les marques sont affichées). Et non plus celle que j'avais initialisé via la recherche. Et le "détail de la marque" correspond au numéro d'index de la première DataTable affichée et non pas celle de la recherche. Egalement, le contenu de la recherche saute (le champ de recherche est vide) C'est comme si ma méthode PostConstruct init() était invoqué à chaque fois que je clique sur une ligne de la table ou qu'une nouvelle instance de mon contrôleur était appelée. Exemple:

dataTable de base:
Asus
HP
Lenovo

Nouvelle DataTable affichée après recherche avec un o:
Lenovo

Et quand je clique sur Lenovo---->
Asus
Hp
Lenovo

Détail----> nom de la marque: Asus


Il me refresh donc chaque fois ma DataTable de base mais je ne comprends pas où vu que mon DataModel est bien instancié par la recherche.
Bref, j'ai pensé à plein de trucs (portée du backing bean, mauvaise gestion du CommandLink,...) mais toutes mes recherches se sont avérées veines. :/

Je vous donne le code de ma page xhtml (en gras, la partie DataTable)

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
<?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://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Facelet Title</title>
        <h:outputStylesheet name="jsfcrud.css"/>
    </h:head>
    <h:body>
        <ui:composition template="/template.xhtml">
            <ui:define name="top">
                <h2>Gestion des marques</h2>
            </ui:define>
            <ui:define name="search">
                <h:form id="searchF">
                    <table>
                        <tr>
                            <td>Nom de la marque&nbsp; </td>
                            <td><h:inputText id="name"
                                             value="#{brandCtrl.search.name}" 
                                             /></td>

                        </tr>
                        <tr>
                            <td> <h:commandButton value="Rechercher" 
                                                  action="#{brandCtrl.doSearch()}"></h:commandButton> 
                            </td>
                        </tr>
                    </table>
                </h:form>
            </ui:define>
            
            
            <ui:define name="list">
                <h:form id="listF">
                    <h:dataTable value="#{brandCtrl.items}" var="b" border="1">
                        
                        <h:column>
                            <f:facet name="header">
                                <h:outputText value="Nom PC"/>                             
                            </f:facet>
                            <h:commandLink value="#{b.name}"
                                           action="#{brandCtrl.prepareEdit}"/>
                        </h:column>
                        
                    </h:dataTable> 
                </h:form>
            </ui:define>
            
            
            <ui:define name="detail">
                <h:form id="detailF">
                    <table>
                        <tr>
                            <td>Nom</td>
                            <td><h:inputText id="name"
                                             value="#{brandCtrl.current.name}"
                                             style="width: 150px"/> </td>
                        </tr>
                    </table>

                    <h:commandButton value="Nouvelle marque"
                                     action="#{brandCtrl.doNewBrand()}"
                                     />
                    <p></p>
                    <p></p>
                    <div id = "cadrePC">
                        <table width="20px" >
                        
                        <tr border="20px">
                            <h:commandButton value="Sauver"/>
                            <h:commandButton value="Supprimer"/>
                        </tr>
                    </table>
                    </div>
                </h:form>

            </ui:define>
        </ui:composition>
    </h:body>


</html>

Et le contrôleur.

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 */
@javax.faces.bean.ManagedBean(name = "brandCtrl")
@SessionScoped
public class BrandCtrl implements Serializable {
 
    @EJB
    be.isl.log.computer.business.BrandEJB brandejb;
    BrandSearch search;
    Brand current;
    DataModel items = null;
 
    public BrandCtrl() {
    }
 
    @PostConstruct
    public void init() {
 
        items = new ListDataModel(brandejb.findAll());
        current = (Brand) items.getRowData();
        search = new BrandSearch();
 
    }
 
    public BrandEJB getBrandejb() {
        return brandejb;
    }
 
    public void setBrandejb(BrandEJB brandejb) {
        this.brandejb = brandejb;
    }
 
    public BrandSearch getSearch() {
        return search;
    }
 
    public void setSearch(BrandSearch search) {
        this.search = search;
    }
 
    public Brand getCurrent() {
        return current;
    }
 
    public void setCurrent(Brand current) {
        this.current = current;
    }
 
    public DataModel getItems() {
        return items;
    }
 
    public void setItems(DataModel items) {
        this.items = items;
    }
 
    public String prepareEdit() {
        current = (Brand) items.getRowData();
        return "brand.xhtml";
    }
 
    public String doSearch() {
        List<Brand> brands = brandejb.find(search);
        if (brands != null && brands.size() > 0) {
            items = new ListDataModel(brands);
            current = (Brand) items.getRowData();
        } else {
            items = null;
            current = null;
        }
        return "brand.xhtml";
    }
 
    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(brandejb.findAll(), true);
    }
 
    @FacesConverter(forClass = Brand.class)
    public static class BrandCtrlConverter implements Converter {
 
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            BrandCtrl controller = (BrandCtrl) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "brandCtrl");
            return controller.brandejb.find(getKey(value));
        }
 
        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }
 
        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }
 
        public String getAsString(FacesContext facesContext, UIComponent component,
                Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Brand) {
                Brand o = (Brand) object;
                return getStringKey(o.getBrandId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type "
                        + object.getClass().getName() + "; expected type: "
                        + Brand.class.getName());
            }
        }
    }
 
}
Et l'EJB brand au cas où...

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
 */
@Stateless
public class BrandEJB {
 
    @PersistenceContext(unitName = "LOG_Computer_FBPU")
    EntityManager em;
 
    public List<Brand> findAll() {
        return em.createNamedQuery("Brand.findAll").getResultList();
    }
 
    public Brand find(Object id) {
        return em.find(Brand.class, id);
    }
 
    public List<Brand> find(BrandSearch b) {
        String jpql = "SELECT b FROM Brand b ";
        String where = "";
 
        if (b.getName() != null && b.getName().length() > 0) {
            where = "b.name like :name";
        }
 
        if (where.length() > 0) {
 
            jpql += " WHERE " + where;
            Query query = em.createQuery(jpql);
            query.setParameter("name", "%" + b.getName() + "%");
            return query.getResultList();
        }
        return this.findAll();
    }
 
}

Merci d'avance!

Edit: bon ok. Après débugg et avoir testé encore plein de trucs, j'ai l'impression que c'est bien init() qui est appelé à chaque fois. Je n'ai pas dû tout comprendre à mon avis....