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 :

Problème hibernate one-to-many / many-to-one


Sujet :

Hibernate Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 230
    Points : 104
    Points
    104
    Par défaut Problème hibernate one-to-many / many-to-one
    Bonjour,

    J'ai un problème avec une relation bidirectionelle one-to-many many-to-one que je ne comprends pas....je trouve des exemples sur internet mais rien de très précis en terme d'explication.
    Mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Entity
    public class Department {
        @Id @GeneratedValue(strategy = GenerationType.AUTO)
    	private Long id;
     
     
    	private String name;
     
    	@OneToMany(cascade = {CascadeType.ALL}, mappedBy = "department", orphanRemoval = false)
    	private List<Employee> employees = new ArrayList<Employee>();
     
    	// GETTER/SETTER
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    @Entity
    public class Employee {
     
    	@Id @GeneratedValue(strategy = GenerationType.AUTO)
    	private Long id;
     
    	private String name;
     
    	@ManyToOne
    	@JoinColumn(name="DEPARTMENT_ID", nullable = true)
    	private Department department;
     
    	// GETTER/SETTER
    Mon mapping est comme celui car le schéma de la base de données ne peut être modifié et il n'y a pas de table d'association/liaison entre ces 2 tables.

    Mainenant mon code qui pose problème :
    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
     
    Department department = new Department("DEPARTMENT 1");
    department.getEmployees().add(new Employee("Pierre", department));
    department.getEmployees().add(new Employee("Jean", department));
     
    // Création du département et de 2 employés
    Session session = HibernateUtil.currentSession();
    Transaction tx = session.beginTransaction();
     
    department=(Department)session.merge(department);
     
    tx.commit();
    HibernateUtil.closeSession();
     
     
    department.getEmployees().remove(0);
    department.getEmployees().add(new Employee("Tito", department));
     
    session = HibernateUtil.currentSession();
    tx = session.beginTransaction();
     
    session.merge(department);
     
    tx.commit();
    HibernateUtil.closeSession();
    Tout se passe bien au niveau de la création du département et de mes 2 employés.
    C'est ensuite que cela se gatte....je souhaite supprimer un employé et en rajouter un nouveau.
    Problème, il rajoute bien le nouveau employé, donc le département a maintenant 3 employé mais moi, je souhaiterais qu'il en est que 2, car le premier a été supprimé.
    Je vois que dans les requêtes SQL généré, il ne fait rien pour supprimer l'employé d'index 0 dans ma liste du département: pourquoi ???

    Par contre, si je mets orphanRemoval = true, cela corrige mon problème mais il a supprimé totalement mon employé d'index 0, alors que je souhaite simplement détruire la relation de l'employé d'index 0, qu'il n'appartienne plus à aucun département mais qu'il soit présent en base de donnés...c'est un peu pour ça que j'ai mis nullable = true sur la proprièté Department de l'entité Employee et orphanRemoval = false; au départ pour lui indiquer que j'accepte les orphelins.

    Merci d'avance de vos lumières, conseils....

  2. #2
    Membre chevronné Avatar de jeffray03
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2008
    Messages
    1 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 501
    Points : 2 120
    Points
    2 120
    Par défaut
    Salut
    Tu devrais recuperer l´employé en question set faire un setter(null) sur son departement.

    Eric

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 230
    Points : 104
    Points
    104
    Par défaut
    C'est vrai que c'est une solution mais je dois savoir quels sont les employés qui n'appartiennent plus à ce département.
    En fait, j'aurais aimé que dans la partie cliente, l'utilisateur ajoute, supprime des employés dans le département, sans rien me préoccupait...... et ensuite j'envoie le département avec sa liste d'employées(modifié ou pas par l'utilisateur) et hibernate se débrouille avec un MERGE pour mettre en conformité la base de données avec la liste d'employés du département.

    C'est ce que je fais, un peu dans mon exemple, mon exemple test...en simplifiant à seulement la suppression d'un employé...j'aurais aussi bien pu ajouter, en plus de nouveaux employés....

    C'est pourquoi j'aurais aimé comprendre mon problème décrit dans mon post, savoir pourquoi hibernate a le comportement que je décris dans mon message....

    merci d'avance pour vos explications, conseils... lumières...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Tu as mis en place une relation bidirectionnelle entre Departement et Employé. Donc, il est tout à fait normal, au niveau de ton code java, que tu doive gérer aussi les deux cotés de la relation.


    Tu dois donc faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    departement.remove(0).setDepartment(null);
    Il n'y a rien de sorcier à cela.

    Si tu reste incohérent (d'un coté ta liste d'employés pour département ne mentionne plus tartempion et de l'autre tartempion mentionne qu'il appartient au département), hibernate va être un peu perdu. Mais pas de panique. Avec le mapping que tu as donné, seule la relation employé => département prime pour la mise à jour de la table. L'autre n'est considérée que comme un effet secondaire de la première.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 230
    Points : 104
    Points
    104
    Par défaut
    je reste tjrs sur ma fin concernant l'annotation orphanRemoval :
    si orphanRemoval =false(valeur par défaut) : rien ne se passe avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    department.getEmployees().remove(0)
    si orphanRemoval =true : il supprime l'employé directement...alors c'est sûr que cet employé ne fait plus partie du département(la relation n'existe plus), mais il n'existe plus ..non plus dans la base de données ....il se fout que que je mette le département à null ou pas à l'employé.


    Tu pourrais un peu expliciter quand tu dis
    Mais pas de panique. Avec le mapping que tu as donné, seule la relation employé => département prime pour la mise à jour de la table. L'autre n'est considérée que comme un effet secondaire de la première.
    j'ai un peu de mal à voir la conséquence de ton propos au niveau du code, du fonctionnel mis en place en fonction de qui est le maître de la relation. J'ai lu pas mal d'article sur le web mais ces notions restent flous en terme de ceux que cela peut entrainer comme problème, inconvéniant, avantages ...etc... je suis conscient qu'il faut indiquer à hibernate qui est le maître de la relation dans le cas des relations bidirectionnelle pour l'aider car je l'ai lu....mais je crois qu'il me manque quelques notions pour maîtriser ce que je code dans mes applications, les conséquences derrière...je suis un long à la compréhension, peut-être....
    Tu pourrais expliciter, ou donner des exemples sur ce sujet...

    merci d'avance...

Discussions similaires

  1. One-To-Many/many-to-one order by
    Par crofteur dans le forum Persistance des données
    Réponses: 1
    Dernier message: 18/11/2011, 17h56
  2. [Doctrine] Exemple simple de relation Many:Many et One:Many
    Par llaffont dans le forum ORM
    Réponses: 19
    Dernier message: 07/04/2011, 10h27
  3. hibernate 3 et relation many-to-one
    Par the_frogkiller dans le forum Hibernate
    Réponses: 1
    Dernier message: 01/05/2009, 14h35
  4. Hibernate : suppression sur relation many to one
    Par taf dans le forum Hibernate
    Réponses: 1
    Dernier message: 23/05/2006, 14h08

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