DioBrando
DioBrando

Reputation: 1017

NHibernate - Inheritance Mapping Problem with table per subclass strategy

we changed the mapping from the table per concrete class to the subclass strategy and now the UnitTests fail, but I cannot recognize why.

There's one base class Article and a child one SemifinishedArticle with no specific properties.

Article.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

   <class name="Article" table="cvm_anagrafica_articoli" lazy="true" dynamic-insert="true" dynamic-update="true">



      <id name="Id" column="id" type="integer">
         <generator class="native" >
            <param name="sequence">seq_anagrafica_articoli</param>
         </generator>
      </id>

      <version name="Version" column="versione" unsaved-value="0"/>

      <property name="Code" column="codice" />
      <property name="Description" column="descrizione" />

      <discriminator column="ArticleType" type="string"/>

      <subclass name="SemifinishedArticle" discriminator-value="S" />
   </class>
</hibernate-mapping>

SemifinishedArticle.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

    <subclass name="SemifinishedArticle" extends="Article" lazy="true" >


    </subclass>
</hibernate-mapping>

SemifinishedArticle.cs

Public Class SemifinishedArticle
    Inherits Article

End Class

Error Message:

Initialization method CVM050__Recipe_Management_Test.ArticleMappingTest.MyTestInitialize threw exception. NHibernate.MappingException: NHibernate.MappingException: Coveme.Core.Article.hbm.xml(52,4): XML validation error: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'discriminator' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'property, many-to-one, one-to-one, component, dynamic-component, properties, any, map, set, list, bag, idbag, array, primitive-array, join, subclass, joined-subclass, union-subclass, loader, sql-insert, sql-update, sql-delete, filter, resultset, query, sql-query' in namespace 'urn:nhibernate-mapping-2.2'. ---> System.Xml.Schema.XmlSchemaValidationException: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'discriminator' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'property, many-to-one, one-to-one, component, dynamic-component, properties, any, map, set, list, bag, idbag, array, primitive-array, join, subclass, joined-subclass, union-subclass, loader, sql-insert, sql-update, sql-delete, filter, resultset, query, sql-query' in namespace 'urn:nhibernate-mapping-2.2'..

Error Stack Trace:

NHibernate.Cfg.Configuration.LogAndThrow(Exception exception) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 340
NHibernate.Cfg.Configuration.ValidationHandler(Object o, ValidationEventArgs args) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 1838
System.Xml.Schema.XmlSchemaValidator.SendValidationEvent(ValidationEventHandler eventHandler, Object sender, XmlSchemaValidationException e, XmlSeverityType severity)
System.Xml.Schema.XmlSchemaValidator.ElementValidationError(XmlQualifiedName name, ValidationState context, ValidationEventHandler eventHandler, Object sender, String sourceUri, Int32 lineNo, Int32 linePos, XmlSchemaSet schemaSet)
System.Xml.Schema.XmlSchemaValidator.ValidateElementContext(XmlQualifiedName elementName, Boolean& invalidElementInContext)
System.Xml.Schema.XmlSchemaValidator.ValidateElement(String localName, String namespaceUri, XmlSchemaInfo schemaInfo, String xsiType, String xsiNil, String xsiSchemaLocation, String xsiNoNamespaceSchemaLocation)
System.Xml.XsdValidatingReader.ProcessElementEvent()
System.Xml.XsdValidatingReader.ProcessReaderEvent()
System.Xml.XsdValidatingReader.Read()
System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
System.Xml.XmlDocument.Load(XmlReader reader)
NHibernate.Cfg.Configuration.LoadMappingDocument(XmlReader hbmReader, String name) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 1776
NHibernate.Cfg.Configuration.AddXmlReader(XmlReader hbmReader, String name) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 1813
NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 628
NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 666
NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly) in d:\CSharp\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs: line 761
CVM050__Recipe_Management_Test.DbTestsBase`1.Init(Assembly[] assembliesWithMappings) in C:\UsersData\jcocchi\CVM050 - Recipe Management\Trunk\src\CVM050 -Recipe Management Test\DBTestsBase.cs: line 44
CVM050__Recipe_Management_Test.ArticleMappingTest.MyTestInitialize() in C:\UsersData\jcocchi\CVM050 - Recipe Management\Trunk\src\CVM050 -Recipe Management Test\ArticleMappingTest.cs: line 58

Thanks guys

Upvotes: 0

Views: 1737

Answers (2)

Diego Mijelshon
Diego Mijelshon

Reputation: 52745

  1. SemifinishedArticle.hbm.xml is redundant (it's already defined along with Article)
  2. <discriminator> goes between <id> and <version>. The order is important in the NH schema.

Anyway, you're setting yourself for trouble by having a SemifinishedArticle class: What are you going to do when it is finished? Delete it and insert an Article? Remember you can't change the class of an object.

It's better to add an ArticleState property.

Upvotes: 3

Rippo
Rippo

Reputation: 22424

In article.hbm.xml why do you have?

<subclass name="SemifinishedArticle" discriminator-value="S" />

This should be in SemifinishedArticle.hbm.xml

Upvotes: 1

Related Questions