Mapping list many-to-many
Bonjour à tous,
Je suis débutant sous hibernate, et ca fait plusieurs jours que je cherche une solution. J'ai regardé de nombreux forum et la doc d'hibernate, j'ai beaucoup d'éléments de réponses, mais je n'arrive pas à implémenter correctement pour faire ce que je veux (qui est surement très simple).
configuration : Hibernate + Eclipse + MySql
J'ai des Utilisateur (classe User), qui contiennent notemment une liste de catégories choisies (classe Category). nb : une catégorie peut être attachée à plusieurs utilisateurs.
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
public class User
{
private int id = -1;
private String login;
private String pwd;
private String name;
private String firstname;
private List categories = new ArrayList();
... |
Donc j'ai une relation many-to-many avec 3 tables : category, user, et categoryset (clé primaire : double clée étrangère)
Déjà, est ce que je me trompe sur ce point ?
Ensuite, je configure les fichiers de mapping. Voici mon dernier essai :
Code:
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 26 27 28 29 30 31 32 33
|
<hibernate-mapping package="model">
<class name="model.User" table="user" dynamic-update="true">
<id name="id" type="integer" unsaved-value="-1">
<column name="NUM_USER" sql-type="int(6)"/>
<generator class="increment" />
</id>
<property name="name" type="string">
<column name="NOM_USER" sql-type="char(25)" not-null="true"/>
</property>
<property name="firstname" type="string">
<column name="PRENOM_USER" sql-type="char(25)" not-null="true"/>
</property>
<property name="login" type="string">
<column name="LOGIN_USER" sql-type="char(25)" not-null="true"/>
</property>
<property name="pwd" type="string">
<column name="PASSW_USER" sql-type="char(25)" not-null="true"/>
</property>
<bag name="categories" table="CATEGORYSET" cascade="all">
<key column="USER_ID"/>
<many-to-many class="model.Category" column="CAT_ID" />
</bag>
</class>
</hibernate-mapping> |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
<hibernate-mapping package="model">
<class name="Category" table="category" dynamic-update="true">
<id name="id" type="integer" unsaved-value="-1">
<column name="NUM_CAT" sql-type="int(6)"/>
<generator class="increment" />
</id>
<property name="name" type="string">
<column name="NOM_CAT" sql-type="char(25)" not-null="true"/>
</property>
<property name="description" type="string">
<column name="DESC_CAT" sql-type="char(200)" not-null="true"/>
</property>
<bag name="users" table="CATEGORYSET" inverse="true" cascade="all">
<key column="CAT_ID" />
<many-to-many class="model.User" column="USER_ID" />
</bag>
</class>
</hibernate-mapping> |
Deuxième question subsidiaire : suis-je obligé de faire figurer le bag du fichier de mapping des catégories par une liste d'utilisateurs pour chaque catégorie dans mon fichier java ? car en réalité je n'en ai pas besoin..
Code:
1 2 3 4 5 6 7 8 9
|
public class Category
{
private int id = -1;
private String name;
private String description;
private List users = new ArrayList(); //obligatoire ?
... |
Si oui : dois je bien rajouter l'utilisateur dans la liste dès que la catégorie concernée est choisie par un user ?
Code:
1 2 3 4 5 6
|
public void setOneCategories(Category category)
{
categories.add(category);
category.setOneUser(this);
} |
Je n'ai pas de problème pour l'ajout. Du moins pas encore :)
Je n'ai pas de problème non plus pour la suppression d'un User :
Code:
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 26 27 28 29 30 31 32 33 34 35 36 37
|
public boolean delete(Object o,TypeObjet t) throws HibernateException {
List<String> info = new ArrayList();
switch(t)
{
case user:
User u = (User)o;
info.add(0,u.getName());
info.add(1,u.getFirstname());
User temp = (User)load(info,t);
if(temp != null)
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
temp.removeCategory();
session.update(temp);
session.delete(temp);
tx.commit();
HibernateUtil.closeSession();
System.out.println("L utilisateur a été supprimé");
return true;
}
... |
Par contre, il m'est impossible de supprimer une catégorie : J'ai une exception du type "impossible de supprimer un enregistrement père : une contrainte externe l'en empêche".
J'ai essayé de multiples configurations (on-delete="cascade", cascade="all-delete-orphan", etc... ), mais rien n'y change, ou alors je me retrouve avec des erreurs de compil pour cause de mapping incorrect.
en attendant, j'ai contourné le problème : je charge tout les utlisateurs, je cherche pour chacun d'entre eux si ils ont choisis la catégorie en cours de suppression, si oui je la supprime de la liste et je met à jour le user. Puis à la fin je supprime la catégorie. Mais bon, c'est surement pas comme ca qu'il faut s'y prendre, j'ai un peu l'impression de réinventer la roue ...
J'espère avoir été assez clair, si quelqu'un peut m'aider à supprimer une catégorie ca serait très sympa :)
merci d'avance