-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Delete on cascade
PostPosted: Thu Mar 27, 2008 9:08 am 
Newbie

Joined: Thu Mar 27, 2008 8:44 am
Posts: 8
Bonjour à tous,
J'utilise Hibernate 3 et je développe une appli de gestions d'utilisateurs. Un utilisateur peut s'enregistrer sur plusieurs sites. J'ai donc trois tables : USER, SITE et USER_SITE.

Je rencontre un problème lorsque je veux supprimer un user : au lieu de supprimer les lignes concernées par le user dans ma table USER_SITES, hibernate fait un update en essayant de mettre le USER à null, ce qui génère une erreur puisque un user ne peut pas être null dans ma table USER_SITES.

Je pense que j'ai mal fait mon mapping ou qu'il faut que je m'y prenne autrement mais je ne trouve pas de solutions ...

Voici mon mapping :

USER
Code:
<hibernate-mapping>
    <class name="User" table="users">
   
    <id name="id" type="integer">
       <generator class="increment"/>       
    </id>
   
    <property name="title">
        <column name="title"/>
    </property>

    <property name="lastname">
        <column name="last_name"/>
    </property>

    <property name="firstname">
        <column name="first_name"/>
    </property>

    <set name="userSites" cascade="all-delete-orphan">
       <key column="user"/>
       <one-to-many class="UserSite"/>
    </set>
   
</class>
</hibernate-mapping>


SITE
Code:
<hibernate-mapping>
    <class name="Site" table="sites">
   
    <id name="id" type="integer">
       <generator class="increment"/>       
    </id>
   
    <property name="name">
        <column name="name"/>
    </property>

    <set name="siteUsers">
       <key column="site"/>
       <one-to-many class="UserSite"/>
    </set>
       
</class>
</hibernate-mapping>


USER_SITE
Code:
<hibernate-mapping>
    <class name="UserSite" table="user_site">
   
    <id name="id" type="int">
      <generator class="increment"/>       
    </id>
   
    <property name="validated">
        <column name="validated"/>
    </property>
   
   <many-to-one name="site" class="Site">
     <column name="site" sql-type="number"/>
   </many-to-one>
   
   <many-to-one name="user" class="User">
     <column name="user"/>
   </many-to-one>

</class>
</hibernate-mapping>



Voici le code de l'action de mon DAO qui supprime un user:
Code:
     public void removeUser(final Integer id) {
        try {
           getHibernateTemplate().delete(getUser(id));
        }
        catch( Exception e ) {
           log.error("removeUser: ", e);
        }
     }


Et la requête générée par Hibernate:
Code:
Hibernate: select this_.id as id5_0_, this_.last_name as last3_5_0_, , this_.first_name as first5_5_0_ from users this_ where this_.id=?
Hibernate: select user0_.user as user5_1_, user0_.id as id1_, user0_.id as id6_0_, user0_.validated as validated6_0_, user0_.site as site6_0_, user0_.user as user5_6_0_ from user_site user0_ where user0_.user=?
Hibernate: update user_site set user=null where user=?


Voilà, si quelqu'un a une idée ou des conseils pour améliorer tout ça, je suis preneuse :)

Merci


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 27, 2008 9:49 am 
Beginner
Beginner

Joined: Thu Jan 31, 2008 6:35 am
Posts: 27
Salut,

Ton erreur est simple, tu penses base de données et pas objet.

Ton objet USER_SITE n'existe pas. Tu as juste deux objet Site et Client avec une relation N-N entre eux.
Et pour avoir cette relation, l'effet de bord dans la base de données c'est en effet d'avoir une table USER_SITE. Mais au niveau objet... on s'en fou.

USER
Code:
<hibernate-mapping>
    <class name="User" table="users">
   
    <id name="id" type="integer">
       <generator class="increment"/>       
    </id>
   
    <property name="title">
        <column name="title"/>
    </property>

    <property name="lastname">
        <column name="last_name"/>
    </property>

    <property name="firstname">
        <column name="first_name"/>
    </property>

    <bag name="sites" table="USER_SITE">
       <key>
         <column name="USER_UID"/>
       </key>
       <many-to-many class="Site">
         <column name="SITE_UID"/>
       </many-to-many>
     </bag>
   
</class>
</hibernate-mapping>


SITE
Code:
<hibernate-mapping>
    <class name="Site" table="sites">
   
    <id name="id" type="integer">
       <generator class="increment"/>       
    </id>
   
    <property name="name">
        <column name="name"/>
    </property>
       
    <bag name="users" table="USER_SITE">
        <key>
            <column name="SITE_UID"/>
        </key>
        <many-to-many class="User">
            <column name="USER_UID"/>
        </many-to-many>
    </bag>

</class>
</hibernate-mapping>


Simplement.

Pensez objet !! Modélisez en UML, ça aide.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 27, 2008 9:55 am 
Newbie

Joined: Thu Mar 27, 2008 8:44 am
Posts: 8
Merci de ta réponse sliard,

mais en fait, je suis obligée de modéliser ma table USER_SITE en tant qu'objet parce que j'ai des attributs dans ma relation entre USER et SITE (exemple : le champ "validated" qui apparaît dans le mapping de ma table USER_SITE), je ne peux donc pas traiter ma relation entre USER et SITE par un many to many :(

A moins que j'ai mal lu et que ce soit possible, si c'est la cas, je veux bien un exemple.

Sinon mon problème reste toujours le même....

Une autre idée ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 27, 2008 10:05 am 
Newbie

Joined: Thu Mar 27, 2008 8:44 am
Posts: 8
Merci à tous ceux qui ont lu mon post, j'ai trouvé la solution

Dans le mapping de ma table USER, j'ai ajouté "inverse = true" :)
Ce qui donne donc le mapping suivant :
Code:
<hibernate-mapping>
    <class name="User" table="users">
   
    <id name="id" type="integer">
       <generator class="increment"/>       
    </id>

    <property name="lastname">
        <column name="last_name"/>
    </property>

    <property name="firstname">
        <column name="first_name"/>
    </property>

    <set name="userSites" [b]inverse="true"[/b] cascade="all-delete-orphan">
       <key column="user"/>
       <one-to-many class="UserSite"/>
    </set>


Voilà !
Merci encore


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.