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 de one-to-many update au lieu de delete insert


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 196
    Par défaut Problème de one-to-many update au lieu de delete insert
    Bonjour bonjour,

    Je vous explique mon problème :

    J'ai deux classes "SUPPORT_RULES" et "MATERIAL_CONFIGURATIONS"

    - Un "SUPPORT_RULES" peut avoir 0-* "MATERIAL_CONFIGURATIONS"

    Ainsi dans ma classe SupportRule j'ai un attribut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private Set<MaterialConfiguration> materialConfigurations;
    Ce que je souhaite, c'est faire un delete de tous les éléments de cette liste puis en insérer de nouveaux.

    j'ai donc créé une nouvelle liste intitulée "selectedMaterialConfigurations" dans laquelle j'ai inséré plusieurs "materialConfiguration". Enfin je met à jour la liste materialConfigurations dans mon supportRule.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    supportRule.setMaterialConfigurations (selectedMaterialConfigurations);
    Le problème c'est qu'au lieu de faire un delete et d'insérer les nouvelles "MaterialConfiguration", hibernate fait une requête de type update.

    Quelqu'un a-t-il déjà rencontré ce type de problème ?

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Si tu veux vraiment supprimer ta collection, tu dois faire un delete explicite sur chaque élément de cette collection, ou passer par une requête.

  3. #3
    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
    les collection sont surchargées par hibernate pour gérer le tracking des éléments. Donc remplace simplement par ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    supportRule.getMaterialConfigurations().removeAll();
    supportRule.getMaterialConfigurations().addAll(selectedMaterialConfigurations);

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 196
    Par défaut
    Ton idée est judicieuse, j'ai essayé mais malheuresement il fait toujours un update.

    J'ai beaucoup de mal à comprendre car un peu avant je fais exactement la même chose, sauf que c'est pour une relation ManyToMany et dans les requêtes SQL je vois bien qu'Hibernate fait un delete de la collection puis un insert.

    Je pense donc que mon problème peut venir du mapping hibernate que voici :

    SupportRule.hbm.xml

    <hibernate-mapping package="com.genigraph.agir.server.model" default-access="field">
    <class name="SupportRule" table="SUPPORT_RULES">
    <id name="id" column="ID" type="long" unsaved-value="0">
    <generator class="native">
    <param name="sequence">SUPPORT_RULES_SEQ</param>
    </generator>
    </id>

    <property name="label" column="LABEL" type="string"/>
    <property name="name" column="NAME" type="string"/>
    <property name="dayType" column="DAY_TYPE" type="string"/>

    <set name="materialConfigurations" table="MATERIAL_CONFIGURATIONS" lazy="true" inverse="true" cascade="all">
    <key column="SRUL_ID"/>
    <one-to-many class="MaterialConfiguration"/>
    </set>
    </class>
    </hibernate-mapping>
    MaterialConfiguration.hbm.xml

    <hibernate-mapping package="com.genigraph.agir.server.model" default-access="field">
    <class name="MaterialConfiguration" table="MATERIAL_CONFIGURATIONS">

    <composite-id name="id" class="com.genigraph.agir.server.persistence.userTypes.MaterialConfigurationId">
    <key-property name="supportRuleId" column="SRUL_ID" type="long"/>
    <key-property name="equipmentClassId" column="EC1_ID" type="long"/>
    </composite-id>

    <property name="quantityMin" column="QUANTITY_MIN" type="int"/>
    <property name="quantityMax" column="QUANTITY_MAX" type="int"/>

    <many-to-one name="supportRule" class="SupportRule" column="SRUL_ID" insert="false" update="false"/>
    <many-to-one name="equipmentClass" class="EquipmentClass" column="EC1_ID" insert="false" update="false"/>

    </class>
    </hibernate-mapping>

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Pour un many-to-many c'est normal, c'est une table d'association dont la clef primaire (non modifiable) est composée de clés étrangères, donc on ne peut que supprimer pour recréer.

    Je persiste à dire que si tu veux supprimer ta collection, tu dois passer par un delete explicite.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 196
    Par défaut
    En fait ce que je cherche a faire c'est pas directement faire un delete sur ma collection, c'est plutôt la mettre à jour en base de données :

    Imaginons qu'au départ j'ai 3 objets dans ma collection (o1,o2,o3).
    Au sein de ma méthode je modifie ma collection (exemple je supprime o2 et j'ajoute un nouvel objet o4)

    Je pensais qu'hibernate se chargeait de synchroniser lui-même les données en base, sans que j'ai a faire un delete et un insert explicite sur ma collection pour enlever o2 et ajouter o4.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Ah ok.
    Ben il faut dans ce cas modifier l'autre côté du lien tonMaterialConfiguration.supportRule(null);

  8. #8
    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
    Ton set est indiqué avec inverse=true. Ca veux dire que ce n'est pas lui qui gère la collection. C'est la relation MaterialConfiguration-> SupportRule qui gère. Donc ce que tu dois faire ce n'est pas ajouter / supprimer dans le set mais appeler les divers MaterialConfiguration.setSupportRule.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 196
    Par défaut
    Donc j'ai enlevé le inverse="true" car je veux que ce soit le set qui gère la collection.

    Au final je comprends bien ce qui ne marche pas mais je n'arrive pas à résoudre le problème. En fait tout se passe bien pour l'insertion où la modification d'un MaterialConfiguration dans mon set.

    Le problème vient au niveau de la suppression.
    Je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    supportRule.getMaterialConfigurations ().removeAll()
    et j'obtiens l'erreur suivante : impossible de mettre à jour ("AGIR_PAG"."MATERIAL_CONFIGURATIONS"."SRUL_ID") avec NULL

    J'en déduis que lorsque j'enlève un materialConfiguration dans mon set, il met à jour le champ SRUL_ID dans ma classe MATERIAL_CONFIGURATION pour signifier que le materialConfiguration n'est plus associé avec le supportRule.

    Cela fonctionnerait très bien si le champ SRUL_ID ne faisait pas partie de la clé primaire dans ma classe MATERIAL_CONFIGURATION et comme un champ de la clé primaire ne peut être updater à null j'obtiens l'erreur suivante.

    Du coup je me demande comment résoudre mon erreur...

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Fais un delete sur ton objet MaterialConfiguration et un remove côté SupportRule.

  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
    en revoyant ton design, il n'a pas de sens.

    Tu dit que "MATERIAL_CONFIGURATIONS"."SRUL_ID" fait partie de la clé primaire, alors ce champ ne peux jamais être modifié (on ne change pas une clé primiare après stockage de la données). Si tu veux pouvoir dissocier une matérialconfiguration d'une support rule, la support rule ne doit pas faire partie de la clé primaire.

    Aussi, comme tu as une relation bidirectionnelle (supportrule <->materialconfiguration), un des deux cotés doit être marqué comme inverse=true pour hibernate.

Discussions similaires

  1. Problème hibernate one-to-many / many-to-one
    Par valkeke dans le forum Hibernate
    Réponses: 4
    Dernier message: 02/04/2014, 14h06
  2. [NHibernate] problème de relation one-to-many
    Par Spikuria dans le forum NHibernate
    Réponses: 1
    Dernier message: 30/04/2009, 14h22
  3. Problème de delete sur one-to-many avec une cascade
    Par Theoden dans le forum Hibernate
    Réponses: 2
    Dernier message: 02/01/2009, 17h43
  4. Problème avec <one-to-many>
    Par SyLvErStOrM dans le forum Hibernate
    Réponses: 7
    Dernier message: 09/09/2008, 10h02
  5. Hibernate3 : Problème d'insert avec one-to-many
    Par myocean dans le forum Hibernate
    Réponses: 2
    Dernier message: 22/02/2008, 10h04

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