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 :

Suppression dans collection


Sujet :

Hibernate Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut Suppression dans collection
    Bonjour,

    Je travaille sur une appli Web qui utilise Hibernate pour la gestion de la persistance.

    Certains de mes objets contiennent des listes d'éléments que l'utilisateur peut manipuler dans l'interface graphique (ajout, modif, suppression).

    Tout marche bien sauf pour la suppression d'un élément d'une liste.
    Dans ce cas précis, Hibernate me met bien à jour l'objet principal mais ne supprime pas l'élément qui n'existe plus dans une de ses listes.

    Alors j'ai lu quelque part qu'en plus du "cascade='all-delete-orphan'" il fallait mettre à null le père dans l'élément de la collection à supprimer.
    Le problème c'est que quand je récupère mon objet du côté serveur, ben cet objet n'existe déjà plus, puisque supprimé du côté serveur.

    Pour moi c'est un problème "basique" qui devrait être gérer par Hibernate, mais apparemment c'est pas aussi simple que ça.

    Quelqu'un a une solution ?

    Voici le mapping de la liste en question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <bag name="documents" table="DOCUMENTATION" lazy="false" inverse="true" cascade="all-delete-orphan">
    			<key column="ID_PERE" foreign-key="ID"/> 
    	  		<one-to-many class="Document"/>
    		</bag>
    Et Voici le mapping de l'élément contenu dans la liste :

    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
     
    <class name="Document" table="DOCUMENTATION">
    		<id name="id" column="ID">
    			<generator class="sequence">
          			<param name="sequence">SEQ_DOCUMENTATION</param>
        		</generator>
    		</id>
     
    		<property name="chemin" column="CHEMIN"/>
    		<property name="commentaire" column="COM"/>
    		<property name="extension" column="EXT"/>
    		<property name="nom" column="FICHIER"/>
     
    		<many-to-one name="pere" class="PERE" column="ID_PERE" lazy="false" cascade="all"/>
     
     
    	</class>
    ps : l'association est bidirectionnelle, c'est peut-être ça qui bloque ?

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    A ma connaissance ne fait pas de suppression en cascade, tu devrais effectuer une boucle sur ta collection et supprimer les elements un à un, et enfin supprimer l'element père, c'est d'ailleurs dit quelque part dans la doc d'hibernate.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Tout d'abord merci pour ta réponse.

    Dans l'absolu, une suppression de l'objet père va entrainer une suppression des fils, j'ai déjà pu faire le test, ça marche.

    Par contre moi mon problème c'est dans le cas d'un update du père pour lequel un (ou plusieurs) élément d'une de ses listes a été supprimé par l'utilisateur.

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    J'ai déjà eu à faire à ce cas d'utilisation, pour gérer ca je fais une sauvegarde de l'id du fils selectionné à chaque fois que c fait, à la fin je fais une boucle sur la collection en deletant tous les id que j'avais sauvés. c'est manuel mais ca marche.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Ouais c'est une solution. En fait je fais déjà un truc comme ça : je prends la collection qui m'est retourné par l'utilisateur et je supprime en base tous les éléments qui ne sont pas dedans.

    Le problème c'est que pour le cas qui m'occupe, j'ai environ une dizaine de listes à gérer qu'elles soient rattachées directement à l'objet père ou bien à l'un de ces objets fils

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    essayez

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     	@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    sur vos @OneToMany

    ou regardez l'équivalent en XML (si çà existe…) si vous utilisez des fichiers de configuration et non JPA

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Y a une notation équivalente mais sur le tag <bag> (voir mon premier post).

    Malheureusement, ça ne marche pas. ALors je ne sais pas si c'est hibernate qui ne gère pas ça ou bien si c'est ma config qui ne va pas

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Bon je crois que je vais me palucher ça à la main faute de mieux.

    Mais c'est quand même étrange que ça ne soit pas géré

  9. #9
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Hibernate gère la chose si tu conserves effectivement ta collection d'origine de l'objet, et donc que tu ne la recrées pas avec la Collection que t'impose l'utilisateur.

    Typiquement donc, en sortie de l'IHM, au lieu de créer une Collection et de la coller dans ton objet, il faut prendre fait un get de la Collection qui vient d'hibernate et y effectuer les ajouts / suppressions.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Merci pour ta participation Rei (c'est pas le Collège fou fou fou ?)

    Sinon je ne comprend pas trop ta solution. Je récupère une grappe d'objets que j'envoie à l'utilisateur. Là il fait ses modifications (ajout, suppression) et je récupère ensuite cette grappe modifiée du côté serveur. Et là on fait quoi : on re-récupère les listes via hibernate et on les 'synchronise" avec les listes retournées, ou bien on ne touche pas aux listes dans l'ihm, on ne transmet que le "différentiel" et on fait la synchronisation à la main du côté serveur ?

  11. #11
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par Fichman Voir le message
    Y a une notation équivalente mais sur le tag <bag> (voir mon premier post).

    Malheureusement, ça ne marche pas. ALors je ne sais pas si c'est hibernate qui ne gère pas ça ou bien si c'est ma config qui ne va pas
    Sur ta notation, tu a mis "inverse=true", ce qui signifie que le bag n'est pas le gestionnaire de l'association. En conséquence, supprimer des éléments du bag n'a aucun effet pour hibernante. C'est uniquement en mettant le pere à null que tu déclenche les opérations. Le mieux dans ton cas est de changer la direcitonnalité qui gère l'association, puisque tu veux que ce soit le bag qui la gère. Met donc le inverse sur le mapping de document et non pas sur le mapping du bag

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    J'ai enlevé le inverse=true du bag document, le problème c'est que quand j'enregistre ma liste avec mon objet père, après l'insertion d'un nouveau document, il me fait un update en mettant à null l'id du père dans mon objet Document.... et évidemment ça plante

    Y a quelque chose qui a du m'échapper.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    bon j'ai reglé le problème de l'update à null, mais toujours est-il que la suppression d'un élément dans la collection n'est pas prise en compte

  14. #14
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    on peux voir ton code?

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Tout d'abord, merci de t'occuper d'une âme perdue

    Alors je remets le mapping original :

    L'objet père (extrait)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <class name="Parent" table="PARENT">
     
     
    		<bag name="documents" table="DOCUMENTATION" lazy="false" inverse="true" cascade="all">
    			<key column="ID_PARENT" foreign-key="ID"/> 
    	  		<one-to-many class="Document"/>
    		</bag>
     
     
    	</class>
    L'objet document
    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
     
    <class name="Document" table="DOCUMENTATION">
    		<id name="id" column="ID">
    			<generator class="sequence">
          			<param name="sequence">SEQ_DOCUMENTATION</param>
        		</generator>
    		</id>
     
    		<property name="chemin" column="CHEMIN"/>
    		<property name="commentaire" column="COM"/>
    		<property name="extension" column="EXT"/>
    		<property name="nom" column="FICHIER"/>
     
    		<many-to-one name="parent" class="Parent" column="ID_PARENT" lazy="false" cascade="all"/>
     
     
    	</class>
    Et pour sauvegarder je fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try {
    			HibernateTemplate hbt = this.getHibernateTemplate();
    			hbt.saveOrUpdate(parent);
    		} catch (DataAccessException e) {
                            logger.error("Erreur lors de la sauvegarde du parent");
    			logger.error(e);
    			throw new HibernateException(e);
    		}
    C'est peut-être le saveOrUpdate qui bloque ?

  16. #16
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    le inverse est toujours la. LE cascade="all' n'inclue pas le delete-orphan, c'est probablement pour ca que t'as eu un null qui t'as posé problème dans ta db.

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    Oui pardon.
    Je mets donc ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <bag name="documents" table="DOCUMENTATION" lazy="false" inverse="false" cascade="all-delete-orphan">
    			<key column="ID_PARENT" foreign-key="ID"/> 
    	  		<one-to-many class="Document"/>
    		</bag>
    Et à l'enregistrement du père j'ai cette erreur, alors que je ne supprime pas d'élément dans la liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    impossible de mettre à jour ("FICHMAN"."DOCUMENTATION"."ID_PARENT") avec NULL
    Vu l'erreur, je modifie le mapping comme ceci, on rajoutant un not-null à true dans l'id_parent du document :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <bag name="documents" table="DOCUMENTATION" lazy="false" inverse="false" cascade="all-delete-orphan">
    			<key column="ID_CRI" foreign-key="ID" not-null="true"/> 
    	  		<one-to-many class="Document"/>
    		</bag>

    Et là Hibernate me dit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
     org.hibernate.MappingException: Repeated column in mapping for entity: Document column: ID_PARENT (should be mapped with insert="false" update="false")
    Je m'exécute donc en modifiant le mapping de document :

    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
     
    <class name="Document" table="DOCUMENTATION">
    		<id name="id" column="ID">
    			<generator class="sequence">
          			<param name="sequence">SEQ_DOCUMENTATION</param>
        		</generator>
    		</id>
     
    		<property name="chemin" column="CHEMIN"/>
    		<property name="commentaire" column="COM"/>
    		<property name="extension" column="EXT"/>
    		<property name="nom" column="FICHIER"/>
     
    		<many-to-one name="parent" class="PARENT" column="ID_PARENT" lazy="false" cascade="all" insert="false" update="false"/>
     
     
    	</class>
    Résultat, ça s'enregistre bien mais lorsque je supprime un document de la collection, et bien il ne se passe toujours rien

  18. #18
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Tes mappings devraient plutot ressembler à ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <class name="Document" table="DOCUMENTATION">
    		<id name="id" column="ID">
    			<generator class="sequence">
          			<param name="sequence">SEQ_DOCUMENTATION</param>
        		</generator>
    		</id>
     
    		<property name="chemin" column="CHEMIN"/>
    		<property name="commentaire" column="COM"/>
    		<property name="extension" column="EXT"/>
    		<property name="nom" column="FICHIER"/>
     
    		<many-to-one name="parent" class="PARENT" column="ID_PARENT" lazy="false" cascade="all" inverse="true"/>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <bag name="documents" table="DOCUMENTATION" lazy="false" inverse="false" cascade="all-delete-orphan">
    			<key column="ID_CRI" foreign-key="ID" not-null="true"/> 
    	  		<one-to-many class="Document"/>
    		</bag>

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Par défaut
    L'attribut inverse n'existe pas pour la balise many-to-one

    J'ai même enlevé le not-null = true sur la key du bag et enlever la contrainte correspondante en base.

    A la suppression d'un élément de la collection j'ai bien l'ID_PARENT qui passe à null mais la ligne n'est toujours pas supprimée malgré le delete-orphan.

    Je suis dubitatif

  20. #20
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Citation Envoyé par Fichman Voir le message
    Merci pour ta participation Rei (c'est pas le Collège fou fou fou ?)

    Sinon je ne comprend pas trop ta solution. Je récupère une grappe d'objets que j'envoie à l'utilisateur. Là il fait ses modifications (ajout, suppression) et je récupère ensuite cette grappe modifiée du côté serveur. Et là on fait quoi : on re-récupère les listes via hibernate et on les 'synchronise" avec les listes retournées, ou bien on ne touche pas aux listes dans l'ihm, on ne transmet que le "différentiel" et on fait la synchronisation à la main du côté serveur ?
    Tu peux faire des modifications dans l'IHM, mais il faut que ces modifications soient faites en gardant la collection de base, qui est normalement une collection héritant de PersistentCollection qui stocke les modifications faites à la collection. Ton code côté IHM doit donc éviter de recréer une collection. Maintenant il se peut aussi que l'erreur vienne des attributs du mapping, là j'avoue que je n'ai que survolé
    (Et oui, c'est bien le nom du chef de la bande des joyeux loufoques).

    Edit grammatical ^^

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Suppression dans une collection détachée
    Par romainw dans le forum Hibernate
    Réponses: 1
    Dernier message: 25/11/2008, 12h44
  2. [Debutant]Suppression dans des tables avec contraintes
    Par Roming22 dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 26/10/2004, 17h23
  3. Combler les trous lors d'une suppression dans une table
    Par Billybongjoe dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 08/04/2004, 14h02
  4. [LG]suppression dans une liste chainée
    Par mister_dsg dans le forum Langage
    Réponses: 9
    Dernier message: 16/12/2003, 21h20
  5. [LG]suppression dans un fichier
    Par cedrick essale dans le forum Langage
    Réponses: 5
    Dernier message: 10/08/2003, 15h22

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