Le 27/02/2013 01:50, Eric Chatellier a écrit :
Bonjour,
Je rencontre actuellement un petit problème visible sur la modification d'un document. Lorsque l'on tente de modifier un document existant, le créateur n'est sélectionné avec la bonne valeur.
Le code étant le suivant: final DropDownChoice<Personne> createurInput = new DropDownChoice<Personne>("Document.createur", new PropertyModel<Personne>(documentModel, "createur"), personnes);
Je pense que le problème se situe au niveau des méthodes equals() des entités qui ne sont pas redéfini, l’implémentation par defaut étant 'this == obj', ca peut passer dans la majorité des cas car il y a le cache hibernate, mais dans ce cas la cela ne fonctionne pas.
A code lutin, nous redéfinissons systématiquement le equals() et le hashCode() en fonction des id car il existe toujours. Mais dans le cas de cantharella ils sont générés par la base de données.
Je ne vois pas comment corriger simplement le problème. J'ai testé en ajoutant un equals() rapidement et cela corrige le problème. Re Eric,
Initialement, le choix avait été fait de ne pas redéfinir les equals() et hashCode() et nous avons mis en place pour Cantharella des façons de contourner les désavantages que cela impliquent. Même si ce n'est pas la solution optimale, je ne pense pas que ce soit une bonne idée de revenir sur ce choix aujourd'hui. Cela impliquerait trop d'effets de bords, par conséquent énormément de tests pour vérifier que l'existant fonctionne toujours correctement et pas mal de modifications de codes. Pour être plus exact, tous les equals() et hashCode() ne sont pas redéfinis à part pour les @CompositeId (c'est obligatoire) où c'est à chaque fois la même classe paramétré (CompositeId.java) qui est utilisé. Le hashcode et le equals sont alors redéfinis en se basant sur chaque hashcode ou equals de deux entités qui le compose. Grosso modo, l'inconvénient de ce choix est que deux mêmes objets ne seront pas égaux s'ils proviennent d'une session hibernate différente. Ainsi cela implique que pour comparer deux entités, nous utilisons pas les equals() classiques mais une méthode spécifique qui se basent sur la valeur d'une ou plusieurs propriétés (BeanTools.equals(Object thiz, Object obj, AccessType accessType, String... properties)). De même pour les comparaisons dans une liste, nous n'utilisons pas les contains() et dérivés mais d'autres méthodes statiques de la classe CollectionTools (containsWithValue(...), findWithValue(...), countWithValue(...)). Dans ton cas particulier de liste déroulante, le problème est que Wicket utilise un contains() pour initialiser la liste avec la bonne valeur. Si la liste dans laquelle il recherche l'entité et cette entité recherchée n'ont pas été chargés dans la même session Hibernate, Wicket ne peut pas faire la correspondance avec le contains(). En générale, nous chargeons les objets dans la même session ce qui évite ce problème. Nous avons cependant déjà eu plusieurs cas où il nous a fallu contourné le problème. Cela se passe lors d'une saisie multiple lorsqu'on veut précharger certains champs du formulaire avec ceux du précédent formulaire. Tu peux trouver le code suivant dans la classe ManagePurificationPage, les commentaires expliquent ce cas particulier :
// qd saisie multiple avec préremplissage, hack nécessaire afin d'avoir dans le model le même objet que // celui de la liste de choix (sinon comme les objets viennent de sessions hibernate différentes, on n'a pas // l'égalité entre les objets) purificationModel.getObject().setManipulateur( CollectionTools.findWithValue(personnes, "idPersonne", AccessType.GETTER, purificationModel .getObject().getManipulateur().getIdPersonne()));
Tu devrais normalement t'en sortir avec cet astuce... à moins que tu préfères charger ton objet dans la même session Hibernate que ta liste. Adrien -- Adrien Cheype Ingénieur en Systèmes d'Information Service « Informatique Scientifique et Appui aux Partenaires du Sud » Direction du Système d'Information (DSI) http://www.ird.fr/dsi/ http://www.ird.fr/informatique-scientifique/ INSTITUT DE RECHERCHE POUR LE DEVELOPPEMENT BP A5 - 98848 Nouméa - Nouvelle Calédonie Tél. +687 260 789