Thank you for your answer.
Finally I managed to implement a bidirectional one-to-many relation, with this config for the Parent class:
Code:
<class name="Parent" table="Parent">
...
<set name="children" table="Child" fetch="select" cascade="all-delete-orphan" inverse="true">
...
invere=”true” is the the salient point.
But I'm still facing problems with the bidirectional many-to-many relation.
I tried it that way:
Code:
<class name="Group" table="Groupe">
<id name="id" type="int" column="id">
<generator class="increment" />
</id>
<set name="users" table="UserGroupMember">
<key column="Group_id" />
<many-to-many column="User_id" class="User" />
</set>
</class>
<class name="wrong.many.to.many.User" table="User">
<id name="id" type="int" column="id">
<generator class="increment" />
</id>
<set name="groups" table="UserGroupMember" inverse="true" cascade="all-delete-orphan"> <!-- inverse = true, since i want that the Group adds User as member -->
<key column="User_id" />
<many-to-many column="Group_id" class="wrong.many.to.many.Group" />
</set>
</class>
With this config, creating an User, creating a Group and creating the relationship between them works fine.
Also deleting a Group and the corresponding relationship to User works,
but deleting a User will cause problem, since cascade="all-delete-orphan" let also delete the Groups, where the User was assigned to.
Code:
public void deleteUser(User u)
{
Transaction tx = session.beginTransaction();
for (Group g: u.groups)
{
g.users.remove(u);
session.update(g);
}
u.groups.clear();
session.update(u);
session.delete(u);
tx.commit();
}
I want to delete only the relationship and not the Groups, so cascade="all-delete-orphan" is the wrong flag (like expected). How do I solve this problem?
Whith removing cascade I get this exception:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`UserGroupMember`, CONSTRAINT `FK58E2090EFBE31FA5` FOREIGN KEY (`User_id`) REFERENCES `User` (`id`))
It's clear to me what this Exception will say to me, but i dont know why this exception is thrown, because i thought I could remove this database record with:
Code:
for (Group g: u.groups)
{
g.users.remove(u);
session.update(g);
}
u.groups.clear();
session.update(u);
If I remove inverse than deleting a user works, but i will face other problems like,
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-2' for key 'PRIMARY'
by inserting a new User-Group Relation, because of:
Code:
public void assignUserToGroup(Group g, User u)
Transaction tx = session.beginTransaction();
u.groups.add(g);
g.users.add(u)
tx.commit();
}
Since ther is no inverse set, nobody is the owner of the relation, and both (User and Group) will insert into ther UserGroupMember Database this relation, which will cause the Excpetion.
A solution may be to create the relation via only one Entity:
Code:
public void assignUserToGroup(Group g, User u)
Transaction tx = session.beginTransaction();
u.groups.add(g);
//g.users.add(u)
tx.commit();
System.out.println("CONTAIN"+ g.users.contain(u)); // Is false
}
That works (the relation is saved in the table UserGroupMember correctly and only once), but it brings other problems:
because g.users does not contain the User u.
And to solve this problem i could close and reopen the session:
Code:
public void assignUserToGroup(Group g, User u)
Transaction tx = session.beginTransaction();
u.groups.add(g);
//g.users.add(u)
tx.commit();
// UGLY HACK
session.close();
session = sessionFactory.openSession();
}
By reoping the session the relation will be loaded correctly next time, when you access the user object, but thats a very ugly hack.
There must be a better solution!
Any suggestion?