I'm attempting to map a bidirectional many-to-many relationship between Users and Roles using lists instead of sets to maintain the order. The relevant portions of my mapping files look like this:
Code:
<class name="User" table="User">
<id name="id" column="UserID" type="long">
<generator class="native" />
</id>
...
<list name="roles" table="UserRole">
<key column="UserID" />
<list-index column="RoleIndex" />
<many-to-many column="RoleID" class="Role" />
</list>
</class>
Code:
<class name="Role" table="Role">
<id name="id" column="RoleID" type="long">
<generator class="native" />
</id>
...
<list name="users" table="UserRole" inverse="true">
<key column="RoleID" />
<list-index column="UserIndex" />
<many-to-many column="UserID" class="User" />
</list>
</class>
Hibernate creates the schema properly for all three tables (including the intermediate UserRole join table), and I can add a User and a Role:
Code:
Session session = HibernateUtil.getSession();
Transaction trans1 = session.beginTransaction();
User user = new User();
user.setFirstName("John");
user.setLastName("Doe");
session.save(user);
Role role = new Role();
role.setRolename("Administrator");
session.save(role);
trans1.commit();
The problem happens when I try to relate a User and a Role:
Code:
Transaction trans2 = session.beginTransaction();
user.getRoles().add(role);
role.getUsers().add(user);
trans2.commit();
Hibernate generates the following SQL that does not fill in both list indexes, giving me a not-null constraint violation:
Code:
Hibernate: update public.User set Version=?, FirstName=?, LastLame=? where UserID=? and Version=?
Hibernate: update public.Role set Version=?, Rolename=? where RoleID=? and Version=?
Hibernate: insert into public.UserRole (UserID, RoleIndex, RoleID) values (?, ?, ?)
WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: null
ERROR JDBCExceptionReporter:72 - Batch entry 0 insert into public.UserRole (UserID, RoleIndex, RoleID) values (1, 0, 1) was aborted. Call getNextException to see the cause.
WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: 23502
ERROR JDBCExceptionReporter:72 - ERROR: null value in column "userindex" violates not-null constraint
ERROR AbstractFlushingEventListener:300 - Could not synchronize database state with session
I get a constraint violation regardless of which side is declared inverse="true". I believe I need two list indexes, because there are two lists: The User's list of Roles, and the Role's list of Users.
Is there a way around this problem without having to break up the many-to-many relationship into a pair of one-to-many/many-to-one relationships? The reason is that I would like to avoid the complication of manipulating lists of intermediate UserRole objects if possible.
Bruce