Monday, June 06, 2011

NHibernate Pitfalls: Bags and Join

If you have an entity with a non-lazy loaded bag collection that I fetched using a join, you will get an incorrect number of items when you query a list of this entity: NHibernate will return as many elements as contained by the child table referenced by the bag, plus one for every item in the master table that does not have any child. This happens because NHibernate misinterprets the returned record set.
There are two solutions: either switch to a set, or apply a DistinctRootTransformer:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping default-lazy="false" namespace="SomeNamespace" assembly="SomeAssembly" xmlns="urn:nhibernate-mapping-2.2">
<class name="Order" lazy="false" table="`ORDER`">
<id name="OrderId" access="property" column="`ORDER_ID`">
<generator class="hilo" />
</id>
<property name="Customer" type="String" column="`CUSTOMER`" length="50" />
<set cascade="all-delete-orphan" inverse="true" lazy="false" fetch="join" name="Details">
<key column="`ORDER_ID`" />
<one-to-many class="OrderDetail" />
</set>
</class>
</hibernate-mapping>