I have a scenario in a system which I’ve tried to simplify as best as I can. We have a table of (lets call them) artefacts, artefacts can be accessed by any number of security roles and security roles can access any number of artefacts. As such, we have 3 tables in the database – one describing artefacts, one describing roles and a many-to-many association table linking artefact ID to Role ID.
Domain wise, we have two classes – one for a role and one for an artefact. the artefact class has an IList property that returns a list of roles that can access it. (Roles however do not offer a property to get artefacts that can be accessed).
As such, the nhibernate mapping for artefact contains the following;
<bag name='AccessRoles' table='ArtefactAccess' order-by='RoleID' lazy='true' access='field.camelcase-underscore' optimistic-lock='false'> <key column='ArtefactID'/> <many-to-many class='Role' column='RoleID'/> </bag>
This all works fine and if I delete an artefact, the association table is cleaned up appropriately and all references between the removed artefact and roles are removed (the role isn’t deleted though, correctly – as we don’t want orphans deleted).
The problem is – how to delete a role and have it clear up the association table automatically. If I presently try to delete a role, I get a reference constraint as there are still entries in the association table for the role. The only way to successfully delete a role is to query for all artefacts that link to that role, remove the role from the artefact’s role collection, update the artefacts and then delete the role – not very efficient or nice, especially when in the un-simplified system, roles can be associated with any number of other tables/objects.
I need to be able to hint to NHibernate that I want this association table cleared whenever I delete a role – is this possible, and if so – how do I do it?
Thanks for any help.
Since I was looking for this answer and found this thread on google (without an answer) I figured I’d post my solution to this. With three tables: Role, RolesToAccess(ManyToMany), Access.
Create the following mappings: Access:
Roles:
As mentioned above you can make the RolesToAccess properties protected so they don’t pollute your model.