AFAIK you have just hit a rather weak point of NH (somebody correct me if I am wrong).
If you map:
Code:
<mapping>
...
<bag name="RoundParts">
<one-to-many class="..RoundShape.."/>
</bag>
<bag name="SidedParts">
<one-to-many class="..SidedShape.."/>
</bag>
</mapping>
On initialization NH will not create any conditions to get just the rounded shapes, it will issue a condition to fetch all BaseShape-s.
This willl bring you a nice WrongClassException because it will get at some point a sided shape in the collection of rounded shapes and this will confuse it (or vice versa)
In order to solve this I have used ranges for all subclasses such as:
Code:
BaseShape
--SidedShape 1 (1..10)
----Square 2
----Triangle 3
--RoundShape 11 (11..20)
----Oval 12
----Circle 13
Then, for the mappings you can add a where="discriminator between 1 and 10" to the collection definition to get all SidedShape-s. This will work when the collection are lazy loaded. Unfortunately, with this workaround you will not be able to fetch join this association because the where attribute value will be added to the where clause, not to the join clause.
My best advice would be to use a single collection of all objects. If you will ever need filtering you can use shape.class = MyNamespace.Triangle
in HQL to get all triangles. Criteria does not offer a similar solution, but you can map the discriminator as a read-only column and filter by discriminator.
I don't know how much you have used NH so I will also state that in most scenarios (all but the later) NH will handle the discriminator properly.
I would really like to hear some other opinions for this case!