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

JPA Java Discussion :

Trim des valeurs


Sujet :

JPA Java

  1. #1
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Points : 2 061
    Points
    2 061
    Par défaut Trim des valeurs
    Bonjour,

    j'ai un petit problème avec les champs de type CHAR.
    En effet, dans la base de données les chaines sont enregistrées dans des champs de type CHAR (et ce n'est pas possible de changer cela), ce qui pose problème lors de la récupération des données puisque je suis obligé de trimer toutes les valeurs !

    J'ai dont tenté d'ajouter un entity-listener qui effectue l'action en postLoad et c'est la qu'est le problème, en fait le framework considère que l'entity est modifier après cette action !
    J'ai donc toute mes entities modifier lors des select

    Quelqu'un a une idée de comment contourner ce problème ou un autre moyen de trimer mes entities sans qu'elles soient considérées comme modifiées?

    Merci d'avance
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 974
    Points : 1 825
    Points
    1 825
    Par défaut
    un trigger sur le serveur de la base de données qui déclenche après le "select" . Le trigger faisant le "trim" des char

  3. #3
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par plawyx Voir le message
    un trigger sur le serveur de la base de données qui déclenche après le "select" . Le trigger faisant le "trim" des char
    Un trigger en lecture... un nouveau concept ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Je pense que tu as 2 solutions :
    - passer par un DTO
    - détacher ton entity avant de faire les trim().

    Ce qui est certain, c'est que tant que ton entity est "attaché" à l'entity manager, toutes les modifications effectuées sur un attribut de l'entity feront que le changement sera persisté.
    Personnellement, je préconiserais le DTO...

    Sinon, il y a les bidouilles genre passer par des champs @Transient
    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
     
    class UnObjet
    {
       private Long uid;
       private String nom;
       @Transient private String nom2;
     
       public String getNom()
       {
          return nom;
       }
       public void setNom(String nom)
       {
          this.nom = nom;
       }
       public String getNom2()
       {
          if (nom2 == null)
          {
             nom2 = nom == null ? "" : nom.trim();
          }
          return nom2;
       }
    }
    mais ça suppose que ton application utilisatrice passe par getNom2() et pas getNom()... pas trop naturel peut-être...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 974
    Points : 1 825
    Points
    1 825
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Un trigger en lecture... un nouveau concept ?
    Aîe, la boulette

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Propriétés privees pour le stockage. Et un autre set de propriétés trimmees transient public pour l'usage general.

    Ou alors simplement assumer que ça contient des espaces et l'afficher comme tel.

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Puisque la question est posée dans le forum JPA, voir les annotations de javax.persistence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @PostLoad
    @PrePersist

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    Puisque la question est posée dans le forum JPA, voir les annotations de javax.persistence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @PostLoad
    @PrePersist
    @PostLoad ne répond pas à la problématique, les entities sont encore attachées à ce moment, tout changement de valeur provoquera la persistance en DB.
    On peut tout au plus s'en servir pour initialiser des champs @Transient qui eux seront débarrassés des blancs, mais ça suppose que l'application doit changer de getter pour avoir la valeur attendue par l'application.
    Je n'aime pas trop le principe d'avoir une entity qui fasse un traitement de présentation alors que ce n'est pas son rôle... le DTO est un bien meilleur candidat à mon avis
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Mais un DTO deviens vite une galère à gérer avec les relation one to many. Le problème de base c'est les espaces. Selon moi ils sont là, ils doivent y rester, au reste de l'application de faire avec.

    Ou alors faut fouetter un DBA jusqu'à ce qu'il admette ses erreurs et les corrige...

  10. #10
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Je ne suis pas de ton avis, le DTO est le reflet des données utilisées par une application, si on a besoin d'éléments d'une liaison one-to-many, on les met sous la forme d'une liste de DTO associé au sous-type de la relation.
    L'avantage (pour moi) est qu'on isole l'application d'évolutions futures du modèle physique de données en même temps qu'on ne traite que les données utiles. A la base, c'était surtout utile pour les anciennes DB avec un modèle de données largement obsolète (numérique à la place des dates, noms de colonnes à coucher dehors, etc...) mais j'y trouve un intérêt partout pour nos applications web, surtout couplé avec les composite-components qui gèrent les clés externes.

    Bon, je m'écarte du débat, donc j'en reste là sur les avantages des DTO (il peut aussi y avoir des inconvénients ou une certaine lourdeur à les mettre en oeuvre)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    @PostLoad ne répond pas à la problématique, les entities sont encore attachées à ce moment, tout changement de valeur provoquera la persistance en DB.
    On peut tout au plus s'en servir pour initialiser des champs @Transient qui eux seront débarrassés des blancs, mais ça suppose que l'application doit changer de getter pour avoir la valeur attendue par l'application.
    Je n'aime pas trop le principe d'avoir une entity qui fasse un traitement de présentation alors que ce n'est pas son rôle... le DTO est un bien meilleur candidat à mon avis
    non, tout changement ne provoquera pas de persistence en DB : cela dépend de la stratégie de détection des changements...
    et on peut parfaitement la contrôler, et donc tenir compte du processus de "nettoyage" pour "l'annuler" dans ce contexte, même si parfois cela nécessite de quitter le niveau d'abstraction JPA et de "descendre" dans la couche ORM…

    On peut aussi considérer le problème de la gestion des champs CHAR de la DB plus comme un "legacy cross-cutting concern" que comme un problème de présentation et donc que cela, au contraire, n'a rien à faire dans un DTO…
    Cela dépendra du contexte : si la gestion des CHAR est récurrent dans plusieurs contextes applicatifs de l'entreprise mieux vaut investir dans une solution de base qui sera partagée, et qui de toute façon ne sera qu'un petit surcout dans le développement de la couche persistence commune, en particulier de la gestion correction du optimistic/pessimistic locking, si au contraire une seule application n'est concernée que par quelques rares champs, un sparadrap au niveau du DTO peut suffire.

  12. #12
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    non, tout changement ne provoquera pas de persistence en DB : cela dépend de la stratégie de détection des changements...
    et on peut parfaitement la contrôler, et donc tenir compte du processus de "nettoyage" pour "l'annuler" dans ce contexte, même si parfois cela nécessite de quitter le niveau d'abstraction JPA et de "descendre" dans la couche ORM…
    Comment ? Et surtout, comment fait-on dans un contexte JTA ?...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Points : 2 061
    Points
    2 061
    Par défaut
    bonjour et merci de vos réponse !

    je vois que le sujet a provoqué quelques discussions durant le week end

    mon problème est que je n'ai pas la main sur la base et que je parle d'une base dont le nombre de table atteint environ 900 tables et les chaines sont déclarées a environ 95% avec le type CHAR et dans le lot il y a des champs PK de ce type la !
    je me vois donc mal géré au cas par cas le trim sur chaque champs, j'ai donc chercher un moyen de traiter le problème globalement :
    - 1er cas, j'ai tenter un entity-listener (comme indiqué dans mon 1er post), mais j'ai vite compris que mes entité étaient considérés comme modifié après le trim
    - 2eme cas, utilisation d'un converter, mais je me suis rendu compte que les champs de la clé primaire ne sont pas modifier par le converter . on peux potentiellement s'en contenter et générer les PKs manuellement !

    Ai je raté autre chose qui pourrais m’empêcher d'utiliser un converter ? peut on vraiment la considérer comme un solution viable, qu'en pensez vous ?
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par Alkhan Voir le message
    bonjour et merci de vos réponse !

    je vois que le sujet a provoqué quelques discussions durant le week end

    mon problème est que je n'ai pas la main sur la base et que je parle d'une base dont le nombre de table atteint environ 900 tables et les chaines sont déclarées a environ 95% avec le type CHAR et dans le lot il y a des champs PK de ce type la !
    je me vois donc mal géré au cas par cas le trim sur chaque champs, j'ai donc chercher un moyen de traiter le problème globalement :
    - 1er cas, j'ai tenter un entity-listener (comme indiqué dans mon 1er post), mais j'ai vite compris que mes entité étaient considérés comme modifié après le trim
    - 2eme cas, utilisation d'un converter, mais je me suis rendu compte que les champs de la clé primaire ne sont pas modifier par le converter . on peux potentiellement s'en contenter et générer les PKs manuellement !

    Ai je raté autre chose qui pourrais m’empêcher d'utiliser un converter ? peut on vraiment la considérer comme un solution viable, qu'en pensez vous ?
    Donc on s'oriente vers une solution horizontale, pas un sparadrap…

    Pour avancer : quel ORM utilisez-vous ?

    Il y a encore d'autres solutions possibles au niveau de l'ORM :
    - un "user type" : vous fournissez vous-même les méthodes IN/OUT et le equals()…, et c'est la solution qui colle le plus à la couche JDBC, et fonctionnera aussi pour les PK)
    - le mécanisme d'interception de l'ORM qui étant de plus bas niveau vous permettra de faire certaines choses plus facilement
    mais cela dépend de ce que vous utilisez…

  15. #15
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Comment ? Et surtout, comment fait-on dans un contexte JTA ?...
    lisez la doc de l'ORM que vous utilisez…

  16. #16
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    lisez la doc de l'ORM que vous utilisez…
    Quelle avancée !
    Autant dire que tu ne sais pas donner de piste... bref... no comment... Tschüs
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  17. #17
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Points : 2 061
    Points
    2 061
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    Donc on s'oriente vers une solution horizontale, pas un sparadrap…

    Pour avancer : quel ORM utilisez-vous ?

    Il y a encore d'autres solutions possibles au niveau de l'ORM :
    - un "user type" : vous fournissez vous-même les méthodes IN/OUT et le equals()…, et c'est la solution qui colle le plus à la couche JDBC, et fonctionnera aussi pour les PK)
    - le mécanisme d'interception de l'ORM qui étant de plus bas niveau vous permettra de faire certaines choses plus facilement
    mais cela dépend de ce que vous utilisez…
    Je déploie sur wildfly et donc j'utilise son ORM qui est bien sur hibernate, j'avais effectivement vu la possibilité d'implementer UserType.
    je suis peut être un peu idéaliste, mais j'aurais bien voulu resté dans la couche JPA et donc éviter toutes spécificités lié a un quelconque ORM, c'est pourquoi je n'ai pas indiqué avoir vu cette possibilité !
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  18. #18
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Quelle avancée !
    Autant dire que tu ne sais pas donner de piste... bref... no comment... Tschüs
    pouf pouf...

    le "dirty checking" est une problématique de base de tous les ORM et il n'est pas compliqué de trouver les informations nécessaires,
    mais choisir la stratégie d'implémentation dépendra de nombreux facteurs contextuels spécifiques à l'application et son architecture...

  19. #19
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par Alkhan Voir le message
    Je déploie sur wildfly et donc j'utilise son ORM qui est bien sur hibernate, j'avais effectivement vu la possibilité d'implementer UserType.
    je suis peut être un peu idéaliste, mais j'aurais bien voulu resté dans la couche JPA et donc éviter toutes spécificités lié a un quelconque ORM, c'est pourquoi je n'ai pas indiqué avoir vu cette possibilité !
    Un UserType Hibernate pour ce problème prendra moins de 200 lignes, Javadoc compris.
    Il faudra juste qu'il implémente ParameterizedType en plus de UserType pour que vous puissiez donner la longueur du champ dans les paramètres de l'annotation, exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Type(type = "my.package.MyLegacyCharUserType", parameters = { @Parameter(name="length", value="80") })
    Rester dans la couche JPA est un peu illusoire : le "dirty checking" est une responsabilité de l'implémentation (ORM) pas de la spécification (JPA).

    Même en intervenant au niveau des hooks JPA (@PrePersist et C°), il faut quand même analyser la problématique du "dirty checking" qui est aussi du ressort de l'ORM (en collaboration avec vos @Entity), donc au final, avec Hibernate, le UserType peut s'avérer la solution la plus simple à mettre en œuvre rapidement et sera réutilisable dans des contextes différents car sans aucun impact sur l'implémentation de vos @Entity, hormis le fait de devoir ajouter une annotation sur certains champs.

Discussions similaires

  1. Tri des valeurs dans un DBGrid
    Par soviet dans le forum C++Builder
    Réponses: 3
    Dernier message: 11/06/2015, 14h18
  2. [Math]Problème troncage ou arrondi sur des valeurs
    Par Carrel dans le forum Général Java
    Réponses: 6
    Dernier message: 07/10/2009, 15h11
  3. Décaler des valeurs dans un tableau
    Par sh2003 dans le forum Langage
    Réponses: 6
    Dernier message: 20/03/2004, 16h01
  4. [SQL] Ma requête m'oblige à saisir des valeurs manuellement
    Par bossun dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 22/10/2003, 13h29
  5. Réponses: 6
    Dernier message: 04/04/2003, 15h28

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