NHibernate and Cuyahoga part 2: mappings
When using a powerful O/R mapper like NHibernate, mapping classes to the database can sometimes be tricky. This causes a lot of frustration, especially because there are not so many real-world mapping examples to find (that is, for NHibernate, for the Java version there is much more documentation).
Note: for a better understanding of this article it’s advisable to have the Cuyahoga source code by hand. There will be some references to the source code in the article.
Mapping files
The mapping files are organized like in most other NHibernate examples. There is a single .hbm.xml file for each domain class that contains the mappings. The files are compiled as embedded resource into the assemblies. You can find the mapping files together with the domain classes in the Cuyahoga/Core/Domain folder.
In the modules, the mapping files are in the same folder as the other module files (the Articles module is the best example here).
Common aspects of the Cuyahoga mapping files
Most mapping files have two things in common:
- Primary key values are auto-generated by the database. This results in the following element in the mapping file:
<id name="Id" column="nodeid" type="Int32" unsaved-value="-1">
<generator class="native">
<param name="sequence">cuyahoga_node_nodeid_seq</param>
</generator>
</id>
The sequence element is needed for PostgreSQL and with other databases (SQL Server, MySQL) it is just ignored.
- Timestamps are used for optimistic concurrency:
<timestamp name="UpdateTimestamp" column="updatetimestamp" />
It is advisable to use version numbers for this (<version> element), but since Cuyahoga already had updatetimestamp fields in the database before it even used NHibernate, it was easier to do it this way.
So, how can I learn a bit more about mappings?
Well, it’s really too much to explain everything in detail. The best way is to explore the code with a little aid of the Class Diagram and the Database Diagram.
The Cuyahoga.Core.Domain.Node class is perhaps the most interesting to start with. It has several relationships to other classes, including bidirectional ones (yes, the inverse thing) and there is even a sample of how to map an association class (NodePermission).
For the full picture, you also might want to check the code-behind of the Admin pages (Cuyahoga/Web/Admin) to see how you can work with the mapped objects from .aspx pages. These admin pages are more straightforward and easier to understand than, for example, the Cuyahoga.Web.UI..PageEngine class that builds the pages for the end-users.
Reference
The table below gives an indication of the mappings that are in Cuyahoga and where to find these.
Relation type
|
Collection type
|
Mapping file
|
Classes
|
Remarks
|
one-many
|
bag
|
Node.hbm.xml
|
Node <-> Section
|
bi-directional
|
|
|
|
Node <-> Node (parent-child)
|
bi-directional
|
|
|
ModuleType.hbm.xml
|
ModuleType -> ModuleSetting
|
composite element
|
|
map
|
Section.hbm.xml
|
Section -> Settings
|
name-value pairs
|
|
|
|
|
|
|
|
|
|
|
many-many
|
bag
|
User.hbm.xml
|
User -> Role
|
|
|
|
Node.hbm.xml
|
Node -> Role
|
NodePermission as association class, composite element
|
|
list
|
Menu.hbm.xml
|
Menu -> Node
|
|
|
|
|
|
|
many-one
|
N/A
|
Node.hbm.xml
|
Node <- Site
|
bi-directional
|
|
|
|
Node <- Template
|
|
|
|
|
Node <- Node (parent-child)
|
bi-directional
|
|
|
Section.hbm.xml
|
Section <- ModuleType
|
|
|
|
|
Section <- Node
|
bi-directional
|
|
|
Article.hbm.xml (in ArticleModule)
|
Article <- Category
|
|
|
|
|
Article <- Section
|
multi-assembly
|
|
|
|
Article <- User
|
multi-assembly
|
5/11/2005 12:27:00 PM
Published by
Martijn Boland
Category
Developers
Back