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 :

Objet dans un entity


Sujet :

JPA Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 23
    Par défaut Objet dans un entity
    Bonjour,

    J'aimerai savoir, quand vous faites les design de vos entities, est ce que vous "matérialisez" vos relations avec d'autres entities ou directement avec les foreign key de vos tables ?
    Avec l'exemple des exemples, celui que l'on donne toujours : client et commande.
    Dans l'entity client, vous avez une liste d'entity commande. Et dans l'entity commande, vous avez l'entity client (manytoone)

    Seulement, quand par exemple vous voulez créer une commande, comment vous faites pour l'entity client qui se trouve à l'intérieur ? Vous faites à chaque fois une requête à partir de l'entitymanager pour obtenir un entity client initialisé avec toutes les propriétés que vous réinsérez dans l'entity commande que vous voulez actuellement créer ? Ca fait long non ? Ou bien il y a une autre méthode ?

    Merci pour vos réponses et votre expérience dans le domaine.

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    On peut voir les choses sous plusieurs angles...

    On pourrait enlever l'objet Client de Commande et le remplacer par la clé primaire du client tout simplement parce que, à mon sens, on accède à la commande par le client, donc, on a déjà la définition du client.
    Mais il est vrai aussi qu'on peut limiter l'impact de chargement multiple du même "enregistrement" par le lazy loading.

    Tout ça pour dire que, à force de faire des graphes d'objets qui se croisent, on fini par avoir une masse d'informations à charger en mémoire pour juste accéder à une petite information... dommage

    Je pense que quand on modélise une base au travers des entity, il faut faire attention de ne pas inclure ce qui est du registre d'une fonctionnalité secondaire.
    Pour illustrer et continuer sur ton exemple, on pourrait imaginer que ton client a un historique d'adresse ou de numéro de téléphones. L'inclure à l'entity Client ne me parait pas très judicieux, on pourra obtenir l'information par un petit query là où on aura besoin de l'information...

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 23
    Par défaut
    Je comprends ta position. Mais n'es tu pas en train de reproduire le schéma de ta base de données en entities ?

    Je pense que je vais suivre ton conseil mais en ajoutant quand même un manytoone pour le client. Comme c'est du lazy par défaut, il ne va pas le loader. Et s'il le load, alors c'est que besoin il y a eu.

    Tu penses que c'est possible ?
    Je mets par exemple :
    @column pour l'id du client

    et plus loin

    @manytonone etc pour l'objet client

    Quand j'ajoute, j'utilise pas l'objet : comme ça économie de mémoire.
    Et quand j'ai besoin des infos client, je fais un get sur l'objet.

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tit_nouveau Voir le message
    Je comprends ta position. Mais n'es tu pas en train de reproduire le schéma de ta base de données en entities ?
    C'est justement ce qu'il faut éviter, sauf s'il y a un besoin fonctionnel bien sûr

    Citation Envoyé par tit_nouveau Voir le message
    Tu penses que c'est possible ?
    Je mets par exemple :
    @column pour l'id du client

    et plus loin

    @manytonone etc pour l'objet client

    Quand j'ajoute, j'utilise pas l'objet : comme ça économie de mémoire.
    Et quand j'ai besoin des infos client, je fais un get sur l'objet.
    Euh ça, je ne sais pas si c'est possible, je ne l'ai jamais essayé en tout cas...
    Je ne vois pas trop l'intérêt non plus, tu es obligé d'avoir un client pour ajouter une commande, et je laisserais l'objet Client gérer la persistance des commandes (via cascade)

    Tu voudrais persister l'objet Commande seul ?
    Ceci dit, c'est possible aussi, dans tous les cas, tu accèdes au client (ou tu en créé un) avant. Il suffit de "setter" l'objet Client de Commande avant de persister.
    Dans le cas d'une création de client, il faut juste persister Client avant de persister la/les commande(s).
    Si ton problème est lié à un ID primaire généré automatiquement (séquence...), tu peux utiliser "merge" qui te renvoie l'instance de l'objet.

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    383
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 383
    Par défaut
    Il y a deux manières de récupérer des entités de la base :
    - en faisant une requête
    - en naviguant le graphe d'objet avec les relations.

    En général il ne faut créer de relations Hibernate que pour les liens qui vont être utiles à la navigation. C'est à dire qu'en fonction de l'utilisation de l'application par les utilisateurs (en fonction de l'IHM) il faut prévoir dans quel sens on aura besoin de naviguer (par exemple on part toujours du client et on obtiens la liste des commandes).
    Pour les autres cas, on peut toujours faire une requête HQL.

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par slevy Voir le message
    ...
    En général il ne faut créer de relations Hibernate que pour les liens qui vont être utiles à la navigation. C'est à dire qu'en fonction de l'utilisation de l'application par les utilisateurs (en fonction de l'IHM)
    ...
    Je trouve l'approche IHM très discutable pour ma part, je préfère une approche fonctionnelle des entités.
    Pour l'approche IHM, je préfère le concept des DTOs...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 23
    Par défaut
    C'est justement ce qu'il faut éviter, sauf s'il y a un besoin fonctionnel bien sûr
    C'est pour ça en fait que je fais ma modélisation objet sans tenir compte de la bdd. Comme ça, j'ai réellement une conception OO qui va être forcément différente de celle de la bdd. Et j'insère mes annotation ensuite. Merci de m'avoir éclairé sur ce point.

    Tu voudrais persister l'objet Commande seul ?
    Je voudrais juste me libérer de la recherche d'un objet client pour persister une commande. Ton idée d'introduire juste la clé primaire est géniale car ça serait la seule information envoyée par l'interface web sur le net (en plus de ce qui est nécessaire pour la commande). Et quand elle arrive dans mon bean, j'ai juste à remplir l'entity et je persiste.

    Seulement, si je fais comme tu dis, pour la lecture, c'est plus enquiquinant. A moins que je puisse mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @ManyToOne
    private Integer idclient;
    Le cas n'est pas parlant, celui là l'est plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @OneToMany(mappedBy = "idclient", cascade = CascadeType.ALL)
    private Collection<Integer?> commandes;
    A ce moment là, j'aurais un peu de boulot à faire pour récupérer le client pour créer l'entity pour qu'il puisse être totalement sérializable et être renvoyé ensuite vers le web. Chose que j'aurais pu délaisser s'il était possible d'avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    private Integer idclient;
    ....
    plus loin
    ....
    @ManyToOne
    @JoinColumn("idclient")
    private Client leclient;
    Je persiste avec la première variable. Et quand j'ai besoin de renvoyer les infos, je fais un get sur la seconde.

    Mais tu dis que :

    Je ne vois pas trop l'intérêt non plus, tu es obligé d'avoir un client pour ajouter une commande, et je laisserais l'objet Client gérer la persistance des commandes (via cascade)
    Quand tu laisses l'objet client faire le boulot, tu n'as pas besoin de remplir l'entity commande au complet (sans l'ID du client) ? Tu fais juste un add sur ton conteneur de commandes et puis c'est tout ? Est ce que dans ce cas, il faut remplir ton conteneur avant en faisant un get et ensuite ajouter ou bien tu peux ajouter tout de suite alors qu'il est vide (t'as pas encore fait de get dessus puisque c'est lazy) et demander de persister ?

    Si ton problème est lié à un ID primaire généré automatiquement (séquence...), tu peux utiliser "merge" qui te renvoie l'instance de l'objet.
    Un peu dangereux avec merge parce que si tu modifies un truc, il va te le répercuter dans ta base. Mais c'est une solution : à la place de faire une requête, c'est vrai.

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tit_nouveau Voir le message
    Un peu dangereux avec merge parce que si tu modifies un truc, il va te le répercuter dans ta base. Mais c'est une solution : à la place de faire une requête, c'est vrai.
    Fonctionnement de merge
    • s'il y a une instance persistante avec le même identifiant couramment associée à la session, copier l'état de
    l'objet donné dans l'instance persistante

    • s'il n'y a pas d'instance persistante associée à cette session, essayer de le charger à partir de la base de
    données, ou créer une nouvelle instance persistante
    • l'instance persistante est retournée
    • l'instance donnée ne devient pas associée à la session, elle reste détachée
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. [VB.NET] Suppression d'objets dans une collection
    Par master56 dans le forum VB.NET
    Réponses: 7
    Dernier message: 03/06/2010, 21h46
  2. acceder a un objet dans un CPropertySheet
    Par ludoviskm dans le forum MFC
    Réponses: 6
    Dernier message: 21/11/2004, 08h58
  3. [CR9] redimensionner un objet dans la section détail !
    Par LIM dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 27/04/2004, 18h19
  4. Mettre un objet dans un TListView
    Par FredericB dans le forum C++Builder
    Réponses: 4
    Dernier message: 20/04/2004, 09h32
  5. [arbre] Sauvegarder un objet dans un fichier
    Par Guigui_ dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 00h55

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