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 :

[JPA] Fetch lors de la récupération de plusieurs entities


Sujet :

JPA Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Par défaut [JPA] Fetch lors de la récupération de plusieurs entities
    Bonjour,

    J'ai 3 entities (Ecriture, Mouvement et Commentaire) qui sont liées comme suit :
    • Un mouvement contient plusieurs écritures (relation bidirectionnelle)
    • Un mouvement contient plusieurs commentaires (relation unidirectionnelle)


    Je dois faire une requête sur les écritures, mais qui récupère également le mouvement et ses commentaires (qui sont en lazy).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FROM Ecriture e JOIN FETCH e.mouvement m LEFT JOIN FETCH m.commentaires 
    WHERE  m.dossier = :dossier AND m.journal.id IN (:idJournal1) 
    ORDER BY m.annee, m.periode, m.chrono, e.ligne
    Imaginons que la requête doivent me retourner 2 écritures faisant partie du même mouvement et ce mouvement n'a qu'un seul commentaire. Mon problème est que je récupère bien 2 écritures, 1 seul mouvement, mais mon commentaire a été dupliqué. Si c'était un mouvement à 5 écritures, j'aurais eu 5 fois le même commentaire.

    Est-ce que quelqu'un sait où est l'erreur ?

  2. #2
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 25
    Par défaut
    Que veut dire "Dupliqué" ?

    Est-ce le nombre de requêtes SQL générées ? Ou est-ce la présence effective en mémoire de 2 objets commentaires différents. Si je modifie une valeur du premier, le second n'est pas impacté ?

    Pour info, qu'elle est l'implémentation JPA ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Par défaut
    Pour dupliqué, je veux dire que je retrouve plusieurs fois mon commentaire (identiques de par leurs id mais ce sont 2 entities différentes) dans ma liste se trouvant dans mon entity Mouvement.

    j'ai également essayé de mettre 2 commentaires. Dans ce cas, mes écritures ne possèdent plus la même entity Mouvement.


    Voici mes déclarations

    Ecriture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	@ManyToOne
    	@JoinColumn(name="IDMOUVEMENT")
    	private Mouvement mouvement;
    Mouvement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	@OneToMany(cascade=CascadeType.ALL)
    	@JoinColumn(name="IDMOUVEMENT")
    	public List<Commentaire> commentaires;
    et commentaire n'a aucune relation vers mouvement.

  4. #4
    Membre expérimenté Avatar de xv-mnt
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2005
    Messages : 142
    Par défaut
    Ton mapping me semble bizarre :
    Dans la relation OneTomany, tu indiques comme colonne IDMOUVEMENT. Je suppose que cette colonne est dans la table de COMMENTAIRE.
    Je ferais donc une relation ManyToOne de commentaire vers mouvement :
    Commentaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @ManyToOne
    	@JoinColumn(name="IDMOUVEMENT")
    	private Mouvement mouvement;
    et pour mouvement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @OneToMany(mappedBy="mouvement", cascade=CascadeType.ALL)
    	public List<Commentaire> commentaires;
    Comme on a maintenant une relation bi-directionnelle, il faut bnien penser à renseigner les 2 côtés de la relation lors de l'ajout d'un commentaire à un mouvement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void addCommentaire(Commentaire commentaire) {
        commentaires.add(commentaire);
        commentaire.setMouvement(this);
    }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Par défaut
    Mais je n'ai pas besoin de relation bidirectionnelle. Il n'y a aucun intérêt à ce que mes entities Commentaire comportent le mouvement auxquels ils se rapportent.

    Et apparemment, ma relation est correcte, vu que quand je mets le fetchType à EAGER dans mouvement, ça fonctionne.

  6. #6
    Membre expérimenté Avatar de xv-mnt
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2005
    Messages : 142
    Par défaut
    Je conçois que tu n'ais pas besoin de relation bi-directionnelle. Cependant, peux-tu au moins préciser quelle table porte le lien entre MOUVEMENT et COMMENTAIRE car ton mapping me semble incohérent.
    Je répète ce que j'ai dit, je crois que le relation devrait être sur la table COMMENTAIRE. Ainsi tu peux avoir plusieurs commentaires pour 1 MOUVEMENT.

    Peux-tu me confirmer ceci ?

  7. #7
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 25
    Par défaut
    Je suis d'accord avec la remarque de Churchill .

    Il faut savoir qu'une base de données ne stocke réellement que des relations 0,1 (ManyToOne) : En fait elle rajoute une colonne à la table de départ dans laquelle elle stocke la valeur de l'identifiant de l'enregistrement lié.
    Concrétement, il va ajouté dans la table Ecriture une nouvelle colonne IDMOUVEMENT qui contiendra l'identifiant de l'enregistrement Mouvement correspondant.

    La modélisation d'un lien 0,n (OneToMany) dans une base de données relationnelles s'appuie généralement sur le lien retour : il n'est pas possible de stocker les valeurs de plusieurs identifiants correspondant aux 0,n enregistrements dans un nombre inconnu de colonnes.
    Pour être efficace on fait comme le suggère vx-mnt : on ajoute le lien ManyToOne retour (même si on ne s'en sert pas) : cela permet de définir concrètement ce qui va se passer en base de données.

    Pour plus d'info, j'ai fait un tutorial sur les annotations JPA avec un point justement sur les relations OneToMany : http://jl2tho.blogspot.com/2007/08/t...ien-0n-et.html
    .

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/09/2006, 14h40
  2. [MySQL] problème de caractères lors de la récupération des données
    Par lecail65 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 02/08/2006, 16h45
  3. Réponses: 1
    Dernier message: 04/06/2006, 16h08
  4. Réponses: 2
    Dernier message: 09/03/2006, 15h24
  5. [jsp]problème lors de la récupération de paramètre, textarea
    Par money mark dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 12/06/2005, 22h08

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