Next up for inspection is the <many-to-one/> element. This element is defined as:
<many-to-one name="PropertyName" (1) column="column_name" (2) class="ClassName" (3) cascade="all|none|save-update|delete" (4) fetch="join|select" (5) update="true|false" (6) insert="true|false" (7) property-ref="PropertyNameFromAssociatedClass" (8) access="field|property|nosetter|ClassName" (9) unique="true|false" (10) optimistic-lock="true|false" (11) not-found="ignore|exception" (12) />
Much of the attributes on this element are identical to the ones that I outlined in the post about <property/>. 1, 2, 3, 6, 7, 9 and 11 are identical, and I am not going to cover them.
4) cascade is interesting, it controls one of the more interesting NHibernate features, persistence by reachability.I outlined all the possible options in 2006, so I wouldn’t repeat them again.
5) fetch is really interesting. Let us take a look at an entity definition, and explore how modifying it can alter NHibernate’s behavior.
<class name="Post" table="Posts"> <id name="Id"> <generator class="identity"/> </id> <property name="Title" /> <many-to-one name="Blog" column="BlogId"/> </class>
And we have the following code to exercise NHibernate:
using (var session = sessionFactory.OpenSession()) using (var tx = session.BeginTransaction()) { var post = session.Get<Post>(1); Console.WriteLine(post.Title); tx.Commit(); }
This would result in the following SQL.
But interesting things happen when we start playing with the fetch attribute. Note that by default the fetch attribute is defaulting to “select”, so setting it to that value is merely making things explicit, but setting it to fetch=”join”, like this:
<many-to-one name="Blog" column="BlogId" fetch="join"/>
Would result in the following SQL:
We eagerly load the Blog association, in this case.
8) property-ref is a legacy feature, it is meant to allow you to create many-to-one associations when the association is not done on the primary key of the association. In general, I would strongly suggest avoiding it.
9) unique is relevant only if you use NHibernate to specify your schema. This would generate a unique constraint when we generate the DDL.
12) not-found is another legacy feature, it controls how NHibernate behaves when it finds an invalid foreign key. That is, a value that points to an entity that doesn’t exist. By default, this would trigger an error, as this generally indicate a problem with the database, but with legacy database, you can tell it to set the property value to null instead.