6

Here's my heirarchy:

class abstract Entity { /*members*/ } // mapped to entity table
class abstract User : Entity { /*members*/ } // mapped to user table

class Employee : User { /*no members*/ } // no table, discriminator = "E"
class Contractor : User { /*no members*/ } // no table, discriminator = "C"

Here's my mappings in two separate hbm files:

<class name="Entity" table="entity" xmlns="urn:nhibernate-mapping-2.2">
  <id name="Id" column="id">
    <generator class="guid.comb" />
  </id>
  <property ... />
</class>

<joined-subclass name="User" extends="Entity" table="user">
  <key column="id" />
  <discriminator column="type" />
  <property ... />
  <subclass name="Employee"   discriminator-value="E" />
  <subclass name="Contractor" discriminator-value="C" />
</joined-subclass>

The following is the exception I get:

MappingException: XML validation error: The element 'joined-subclass' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'discriminator' in namespace 'urn:nhibernate-mapping-2.2'.

What am I missing? Can you not map a discriminated subclass hierarchy of a joined-subclass?

Joel
  • 7,401
  • 4
  • 52
  • 58
Travis Heseman
  • 11,359
  • 8
  • 37
  • 46

2 Answers2

2

joined-subclass doesn't have a discriminator because it's in a separate table. That's how it knows what the subclass is. If you want to use a discriminator you would use one table for all of your subclasses and you would use the subclass mapping

Vadim
  • 17,897
  • 4
  • 38
  • 62
  • joined-subclasses can be defined in separate files; however, that's beside the point. I think you missed that the "separate table" is the root of a new inheritance hierarchy based on a discriminator. Perhaps you could provide a mapping that will do something similar to what I am puzzled about. – Travis Heseman Jan 24 '11 at 18:32
  • @Travis, interesting re joined subclass. However, your User mapping still has to be a subclass, rather than a joined-subclass, since it's in another table. – Vadim Jan 24 '11 at 18:46
2

What you want to do is not currently possible.

Check http://www.nhforge.org/doc/nh/en/index.html#inheritance for allowed constructs.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
  • So if I understand this right, I can't mix different inheritance strategies? Basically, if every class ultimately descends from a base-class like "Entity", then I have to pick one strategy and that's it for whole hierarchy. I understand not being able to mix at the same level, but is there any chance this will be supported for different levels in the future? – Travis Heseman Jan 24 '11 at 22:06
  • 1
    @Travis, is there a reason you want to have a table for Entity? – Vadim Jan 24 '11 at 22:22
  • Yes; there are 6 fields that are common to all my entities [Id, IsActive, DateCreated, Creator, DateModified, Modifier]. But even if I didn't need Entity, User would take its place in a similar situation if I needed to extend Contractor or Employee. – Travis Heseman Jan 24 '11 at 22:31
  • You usually *never* map the "Entity" class, so that's not an issue. And no, you can't arbitrarily mix strategies beyond what's supported according to the docs. Since it's not a very common need, I doubt it will be supported unless you can provide a fully tested patch for that, which is likely to be really hard, if possible at all, to code. – Diego Mijelshon Jan 24 '11 at 22:35
  • 1
    Disregarding your "never do this or that" comment (I could call Entity something else that is good base class name), the problem is isomorphic to the situation that could always occur when you have both child and grandchild descendant classes where one is joined and the other is discriminated. I think I'll just not use the class per hierarchy at all and use table-per-subclass even for entities with just one column in their table. Thanks for the documentation. – Travis Heseman Jan 24 '11 at 22:46
  • Complex hierarchies do not map very well to a DB performance-wise. – Diego Mijelshon Jan 24 '11 at 23:11
  • I'm learning that most data doesn't map well to RDBMSs in a variety of ways... but creativity is the screwdriver for my nail. – Travis Heseman Jan 24 '11 at 23:16