NHibernate cannot create instance of abstract class - nhibernate

I have a class hierarchy:
Public MustInherit Class SystemSetting
Public Property System As Integer
Public Property Sequence As Integer
Public Property Description As String
Public Property Notes As String
End Class
Public MustInherit Class SystemSetting(Of T)
Inherits SystemSetting
Public MustOverride Property Value As T
End Class
Public NotInheritable Class StringBasedSystemSetting
Inherits SystemSetting(Of String)
Public Overrides Property Value As String
End Class
I have a mapping:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="SystemSettings"
namespace="SystemSettings"
default-lazy="false">
<class xmlns="urn:nhibernate-mapping-2.2"
name="SystemSetting"
abstract="true">
<composite-id>
<key-property name="System" column="SystemId"/>
<key-property name="Sequence" column="SettingSeq"/>
</composite-id>
<discriminator column="SettingType" not-null="true" force="false"/>
<property name="Description" column="SettingDescription"/>
<property name="Notes" column="SettingNotes"/>
<subclass name="StringBasedSystemSetting" discriminator-value="T">
<property name="Value" column="SettingText"/>
</subclass>
</class>
</hibernate-mapping>
This mapping creates the correct schema and allows me to successfully save and flush an object. However, when I query, via LINQ or QueryOver, I get the exception:
Cannot instantiate abstract class or interface
I can resolve this by removing the abstract nature of the SystemSetting class. However, I don't want to compromise my class design if possible. Why is NH trying to create instances of SystemSetting when my mapping is clear on its abstract nature and uses a type discriminator?
Update:
If I replace the composite Id with an assigned Id it works.

I found the answer to this. When a composite Id is used, NH has to use instances of the mapped class to represent the Id. This is why it was trying to instantiate a SystemSetting regardless of the 'abstract' mapping attribute.
Changing the design so that the composite Id is represented as its own type fixes the problem. My base class is still abstract and my queries now work.

Related

NHibernate could not resolve property of an inherited property

Why can't NHibernate access a property inherited from an abstract base class. When I try to use the property in a QueryOver in the Where clause I'm getting
could not resolve property: ID of: TheWorkshop.Web.Models.Customer
var customer = Session.QueryOver<Customer>()
.Where(c=>c.ID ==id)
.SingleOrDefault<Customer>();
Intelisense helped me build the query and the solution compiles, so there is an ID property on the Customer class. The ID property on Customer is inherited from an abstract Contact class that in turn inherits from a DomainEntity<T> which exposes a protected field.
public abstract class DomainEntity<T>
{
protected Guid _persistenceId;
//...
}
public abstract class Contact : DomainEntity<Contact>
{
public virtual Guid ID
{
get { return _persistenceId; }
}
public virtual Address Address
{
get { return _address; }
set { _address = value; }
}
//...
}
and in the mapping file
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="TheWorkshop.Web"
namespace="TheWorkshop.Web.Models"
default-access="field.camelcase-underscore"
default-lazy="true">
<class name="Contact" table="Contacts" abstract="true">
<id name="_persistenceId" column="ID" type="Guid" access="field"
unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb" />
</id>
<!-- ... -->
<union-subclass name="Customer" table="Customers">
Following the answer to a similar question I updated to NHibernate 3.3.3-CR1 from NHibernate 3.3.2.4000 but I still have the same issue.
The problem was that NHibernate couldn't infer from my mapping how to resolve the ID property. So although the classes compiled fine and the _persistenceId property on the abstract base class could be accessed through a getter on the implementing classes, because of the mismatch in names between _persistenceId and ID NHibernate wasn't able to follow that.
The (easier) solution was to change my names to match up. There is a harder solution which involves implementing the IProperyAccessor, IGetter and ISetter interfaces and in order to provide a path to pass the string ID in order to use the ClassName access strategy.
The simpler of the two solutions was just to rename _persistenceId to _id (and update all the references to it) so
<id name="_persistenceId" column="ID" type="Guid" access="field"
unsaved-value="00000000-0000-0000-0000-000000000000">
becomes
<id name="Id" column="Id" type="Guid"
unsaved-value="00000000-0000-0000-0000-000000000000">
Note I was also able to drop the access="field" in the updated id mappings

Do you have to specify the table for an abstract and table-less baseclass when using union-subclass with NHibernate?

We have a BaseEntity of which all our other domain classes inherit. On this BaseEntity are some basic properties. This could be something like DateLastChange for example.
We're using NHibernate with hbm mapping files. I'm trying to avoid having to map DateLastChange in every mapping file.
I found this post by Ayende, which makes me believe I could use union-subclass to achieve this (see his last approach). However, he includes a table name for his abstract class, that isn't in his table-schema.
<class name="Party"
abstract="true"
table="Parties">
...
Does the table have to exist, or will NHibernate just ignore this attribute? And can I then omit it?
This is not needed. As per the documentation (thanks to kalki):
<class name="Payment">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="sequence"/>
</id>
<property name="amount" column="AMOUNT"/>
...
<union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
<property name="creditCardType" column="CCTYPE"/>
...
</union-subclass>
<union-subclass name="CashPayment" table="CASH_PAYMENT">
...
</union-subclass>
<union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
...
</union-subclass>
</class>
And:
If your superclass is abstract, map it with abstract="true". If it is
not abstract, an additional table (it defaults to PAYMENT in the
example above), is needed to hold instances of the superclass.
I have the following abstract class in fluentnhibernate:
public abstract class EntityMapping<TEntity> : ClassMap<TEntity> where TEntity : EntityBase
{
protected EntityMapping()
{
Id(x => x.Id, "Id")
.UnsavedValue("00000000-0000-0000-0000-000000000000")
.GeneratedBy.GuidComb()
.Index("IX_Lookup");
OptimisticLock.Version();
Version(x => x.Version);
Map(x=>x.DateLastChange); // your column
}
}
all other mappings use the abstract class:
public SomeEntityMap:EntityMapping<SomeEntity>{
public SomeEntityMap(){
Map(x=>x.SomeProperty);
}
}

NHibernate constraints associations of a parent class are dropped on the subclass

I think that the main issue is that the subclass deletes all constraints related to the base mapped collections.
Using the table per concrete class strategy, I have found that the parent collections are not asociated with the subclasses also in another (maybe related) problem, the associations between Basetypes and ChildTypes are not created either.
I have a schema similar to this:
public class Parent{
public virtual Int64 Id{get; set;}
public virtual IList<Foo> foos{get; set;}
public virtual IList<ParentType> _pts{get; set;}
}
public class child: Parent{
public virtual int chilInt{get; set;}
}
public class BaseType{
public virtual Int64 Id{get; set;}
public virtual Parent ParentReference{get; set;}
}
public class ChildType: BaseType{
public virtual string childBacon{get; set;}
}
Mapping Files
<class name="Parent" abstract="true">
<id name="Id" type="Int64" column="Id" unsaved-value="0">
<generator class="native"/>
</id>
<set name="foos" inverse="false" >
<key column="Id"/>
<one-to-many class="Foo" />
</set>
<set name="pts" inverse="false" >
<key column="Id"/>
<one-to-many class="ParentType" />
</set>
</class>
<union-subclass name="Child" table="Child" extends="Parent">
<property name="childInt" type="int" />
</union-subclass>
<class name="ParentType" abstract="true">
<id name="Id" type="Int64" column="Id" unsaved-value="0">
<generator class="native"/>
</id>
<many-to-one name="ParentReference" class="Parent"/>
</class>
<union-subclass name="ChildType" table="ChildType" extends="ParentType">
<property name="childBacon" type="string" />
</union-subclass>
The result that the child table don't have any relation with foo table.
If you use the <union-subclass> mapping it's clear that there is no direct relation of the foo entries to your child table because the child table only contains the additional things declared in the child class.
When instantiating a child instance with union-subclass mapping you get a row in both, the parent and child tables. And if your child instance contains entries in the foo set, you get some rows in the foo table with relation to the parent table.
Using table per concrete class mapping does not make sense with associations pointing to the parent class (as the foo class not part of your code example seems to do) because then the different derived classes of parent all inherit the foo set but the foo table cannot have foreign keys to all those tables.
Well, there are three common approaches for ORM and inheritance (table per class hierarchy, table per subclass, table per concrete class). <union-subclass>, one you use, is used in table per concrete class and it should be embedded in parent <class>. Read about it here (8.1.5).
Maybe it won't resolve all your issues, but at least it should help with establishing mapping for inheritance.

How can I map inheritance with subclasses

I have a baseclass that IS NOT abstract and two classes that is based on this class but which have different implemenations in how they calculate the result. The baseclass also inherits from an abstract class that is shared in many different places in the system so I cannot really change that one.
I know that I could extract a baseclass that all three inherits from and just use a normal mapping with subclasses but I just want to know if it is possible to create a hbm file that maps this scenario.
class BaseClass : CalculationBaseClass
{
public virtual int Calculate()
{
...
}
}
class SpecializedClass : BaseClass
{
public override int Calculate()
{
...
}
}
class HistoricClass : BaseClass
{
public override int Calculate()
{
...
}
}
From NHibernate documentation:
NHibernate supports the three basic inheritance mapping strategies.
table per class hierarchy
table per subclass
table per concrete class
You would choose one of the strategies based on what you current table structure is, or if you don't have legacy schema you can just choose the one that is most appropriate for you object model (based on mapped properties for example). In your case, if you use 'table per class hierarchy' you would end up with mapping like this:
<class name="CalculationBaseClass" table="MyTable">
<id name="Id" type="Int64" column="ID">
<generator class="native"/>
</id>
<discriminator column="TYPE" type="String"/>
<subclass name="BaseClass" discriminator-value="BASE">
...
</subclass>
<subclass name="SpecializedClass" discriminator-value="SPECIALIZED">
...
</subclass>
<subclass name="HistoricClass " discriminator-value="HISTORIC">
...
</subclass>
</class>

NHibernate: mapping a dictionary of lists

My class has a field of type Dictionary<string, List<string>>. What's the best way to map it with NHibernate? I'd better leave it as a field, don't want to expose it.
Thanks a lot!
ulu
You can't directly map it. There are two rules to consider:
Always use interfaces for collections (eg. IList<T>, IDictionary<K,V>)
NH does not support nested collections. I've never seen an application for it before
and never heard someone requesting it.
Put your list of string into a class and use interfaces:
class StringList
{
IList<string> Strings { get; private set; }
}
class Entity
{
private IDictionary<string, StringList> stringDict;
}
You might even see some advantages of having such a class.
Mapping:
<class name="Entity">
...
<map name="stringDict" table="Entity_StringDict" access="field">
<key column="Entity_FK"/>
<index column="Key" type="System.String"/>
<composite-element class="StringList">
<bag name="Strings" table="Entity_StringDict_Strings">
<key column="Entity_StringDict_FK"/>
<element type="System.String" column="String"/>
</bag>
</composite-element>
</map>
</class>
Maps to three Tables:
Table Entity
Table Entity_StringDict
Column Entity_FK
Column Key
Table Entity_StringDict_Strings
Column Entity_StringDict_FK
Column String