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

Hibernate Java Discussion :

Hibernate trim() automatique des champs


Sujet :

Hibernate Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 19
    Points
    19
    Par défaut Hibernate trim() automatique des champs
    Bonjour,

    Dans le cadre d'un gros projet d'évolution, j'ai dû intégrer l'utilisation d'hibernate (3.2) au sein de mon application.
    Le framework hibernate remplace désormais l'utilisation de Connexion JDBC directe via Statement, Resultset,...
    Bref, hibernate est en place.

    Cependant, lors de la récupération des valeurs de chaque champs, hibernate ne supprime pas les espaces inutiles.

    Par exemple imaginons une table POSTE avec les champs suivant :
    - ID_POSTE : NUMBER(8)
    - INTITULE_POSTE : CHAR(30)
    - DESCRIPTION_POSTE : CHAR(100)

    Le fichier de mapping serait alors :
    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
     
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd" >
    <hibernate-mapping>
    	<class name="Poste" table="POSTE">
     
    		<!-- Clé -->
    		<id name="idPoste" type="int" unsaved-value="0">
    			<column name="ID_POSTE" sql-type="integer" not-null="true" />			
    			<generator class="sequence">
    				<param name="sequence">SEQ_ID_POSTE</param>
    			</generator>
    		</id>
     
    		<property name="intitule">
    			<column name="INTITULE_POSTE"/>
    		</property>
     
    		<property name="description">
    			<column name="DESCRIPTION_POSTE"/>
    		</property>
    </class>
    </hibernate-mapping>
    Ceci est un exemple mais le nombre de classes et tables associées s'élèvent à une centaine.
    Au moment du chargement de mes objets Poste, la valeur des champs "intitule" et "description" font toujours respectivement 30 et 100 caractères avec des espaces à la fin. Cette taille correspond à la taille des champs dans la base.
    Cet "effet de bord" n'était pas présent avant l'utilisation d'hibernate car une fonction StringUtil.trim() était lors de l'instanciation des objets appliqué lors du parcours des resultset .

    Ma question est : Existe t'il un moyen de supprimer les espaces inutiles lors de l'instanciation de mes objets par hibernate ?

    Je tiens à préciser que pour des raisons de performances évidentes, et de propreté du code je ne peux pas parcourir l'ensemble de mes objets afin d'appliquer la fonction trim() sur les propriétés concernées. On perdrait d'ailleurs tout l'intérêt d'hibernate qui instancie automatique mes objets et rempli les champs.

    Solutions envisagées :
    1) J'ai pensé à effectuer un StringUtils.trim(...) dans les setters de mes propriétés mais je trouve cette méthode plutôt "bourrine" et quelque peu contraignante dans le cas où l'on souhaiterais réellement ajouter des espaces à la fin du champ.
    2) Utilisation de formula trim(NomDuChamp) dans le fichier de mapping hibernate. Mais dans ce cas mes champs se retrouve en lecture seule.

    Donc voilà, je suis un peu coincé. Si quelqu'un à une idée, une réponse, ou un avis.

    Merci d'avance.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 19
    Points
    19
    Par défaut
    Up. C'est toujours d'actualité

    Aucune suggestion ?

  3. #3
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Tu peux utiliser un UserType. Il y a exactement la réponse ici :

    https://forum.hibernate.org/viewtopi...highlight=trim

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 19
    Points
    19
    Par défaut
    Oui merci c'est bon j'ai trouvé !!

    En fait, ce problème n'est présent qu'avec des champs de type CHAR. Avec ce type de donnée la base retourne toujours des chaines de la taille max en complétant par des espaces si la chaine est inférieur à la longueur max. Avec des champs de type VARCHAR pas de problème.
    Voilà pour la précision.

    Donc, pour modifier ce comportement il faut agir sur la manière dont hibernate initialise les champs. La solution consiste à implémenter un nouveau UserType qui sera ensuite appelé dans le fichier de mapping hibernate

    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
     
    public class TrimString implements UserType {
     
    	public Object assemble(Serializable cached, Object owner)
    			throws HibernateException {
    		return cached;
    	}
     
    	public Object deepCopy(Object value) throws HibernateException {
    		return value;
    	}
     
    	public Serializable disassemble(Object value) throws HibernateException {
    		return (Serializable)value;
    	}
     
    	public boolean equals(Object x, Object y) throws HibernateException {
    		if (x == y) {
    	      return true;
    	    } else if (x == null || y == null) {
    	      return false;
    	    } else {
    	      return x.equals(y);
    	    }
    	}
     
    	public int hashCode(Object arg0) throws HibernateException {
    		return arg0.hashCode();
    	}
     
    	public boolean isMutable() {
    		return false;
    	}
     
    	public Object nullSafeGet(ResultSet resultset, String[] names, Object owner)
    			throws HibernateException, SQLException {
    		String result = resultset.getString(names[0]);
    		//Suppression des espaces superflus
    		return StringUtils.trim(result);
    	}
     
    	public void nullSafeSet(PreparedStatement ps, Object value, int index)
    			throws HibernateException, SQLException {
    		String val = (String) value;
    	    ps.setString(index, val);
    	}
     
    	public Object replace(Object original, Object target, Object owner)
    			throws HibernateException {
    		return original;
    	}
     
    	//Il s'agit du type retourné par la méthode nullSafeGet. Nous retournons des objets de type String.
    	public Class returnedClass() {
    		return String.class;
    	}
     
    	public int[] sqlTypes() {
    		return new int[] { Types.CHAR };
    	}
     
    }
    Ensuite dans le fichier de mapping. On spécifie l'attribut "Type" pour les balises property des champs concernés.

    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
     
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd" >
    <hibernate-mapping>
    	<class name="Poste" table="POSTE">
     
    		<!-- Clé -->
    		<id name="idPoste" type="int" unsaved-value="0">
    			<column name="ID_POSTE" sql-type="integer" not-null="true" />			
    			<generator class="sequence">
    				<param name="sequence">SEQ_ID_POSTE</param>
    			</generator>
    		</id>
     
    		<property name="intitule" type="chemin.classe.TrimString">
    			<column name="INTITULE_POSTE"/>
    		</property>
     
    		<property name="description" type="chemin.classe.TrimString">
    			<column name="DESCRIPTION_POSTE"/>
    		</property>
    </class>
    </hibernate-mapping>
    Dans la classe mappée, le type des champs reste String il n'y a rien à changer.

    Voilà.
    En espérant que ça puisse aider quelqu'un.

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

Discussions similaires

  1. [PHP-JS] Chargement automatique des champs
    Par Emir83 dans le forum Langage
    Réponses: 15
    Dernier message: 21/03/2007, 17h34
  2. Aide automatique des champs texte
    Par stailer dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 18/01/2007, 14h22
  3. Réponses: 5
    Dernier message: 03/10/2006, 23h15
  4. Réponses: 4
    Dernier message: 22/05/2006, 15h41
  5. [MySQL] Remplissage automatique des champs d'un formulaire
    Par dodji05 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 21/04/2006, 16h11

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