I want to blog about the approach that I and I am sure countless others use.
You will have to forgive me for the archaic xml mapping files that I am going to use in this example. I have not made the jump to brave new world of the fluent interface of FluentNibernate.
In a typical many-to-many mapping, like the one below, the join table does not exist in the object world:
<bag name="DistributionList" table="DistributionList" lazy="true" cascade="save-update" inverse="true">
<cache usage="read-write"/>
<key column="planuid"/>
<many-to-many class="ncontinuity2.core.domain.Contact,ncontinuity2.core" column="contactuid" not-found="exception"/>
</bag>
But what if we have extra fields in the join table?
If for example, we have the following tables in our database schema:
You can see that the UserPermissions table contains extra fields apart from the two foreign keys of the linking tables. In the above example the UserPermissions join table has the extra fields of viewallowed and editallowed
Here is the mapping I use:
The above mapping is from my user.hbm.xml file that models the user as having a dictionary of composite elements which map to a class named UserPermission.
Here is how this looks in a class diagram:
The following should be noted from the above diagram:
But what if we have extra fields in the join table?
If for example, we have the following tables in our database schema:
You can see that the UserPermissions table contains extra fields apart from the two foreign keys of the linking tables. In the above example the UserPermissions join table has the extra fields of viewallowed and editallowed
Here is the mapping I use:
<map name="UserPermissions" table="UserPermissions" lazy="true" cascade="none">
<cache usage="read-write"/>
<key column="useruid" />
<index column="name" type="String" length="100"/>
<composite-element class="ncontinuity2.core.domain.UserPermission,ncontinuity2.core">
<parent name="User"/>
<property name="ViewAllowed" column="viewallowed" type="Boolean" />
<property name="EditAllowed" column="editallowed" type="Boolean" />
<many-to-one name="Permission" class="ncontinuity2.core.domain.Permission,ncontinuity2.core" column="permissionid" cascade="all"/>
</composite-element>
</map>
The above mapping is from my user.hbm.xml file that models the user as having a dictionary of composite elements which map to a class named UserPermission.
Here is how this looks in a class diagram:
The following should be noted from the above diagram:
- The User object contains a dictionary of UserPermission ojects.
- The UserPermission object contains both the Permission object, which is the other side of the man-to-many relationship and the extra fields of the join table.
Hopefully this gives you another option to achieve the desired result.
I am not saying I am right, I am just saying how I do it.
This was very useful, thanks!
ReplyDelete