I believe that there might be a bug in NHibernate.Util.StringHelper.GetClassname. The code assumes that the last period in a fully-qualified class name immediately precedes the unqualified class name. That is not true for generic classes like the ones in my mapping file, e.g. NUploadedVariable`1[System.Double]. GetClassname gets the unqualified class name of this class as Double].
If I replace the implementation of GetClassname with
Code:
public static string GetClassname( string typeName )
{
string fullClassname = GetFullClassname(typeName);
int splitPos = fullClassname.Substring(0, (fullClassname + "[").IndexOf('[')).LastIndexOf('.');
if (splitPos < 0)
return fullClassname;
else
return fullClassname.Substring(splitPos + 1);
}
it seems to work correctly. I have not thoroughly tested this code or vetted its performance. Also, I have not looked for other places where the same assumption about the form of class names may lead to problems.
Hibernate version:
1.2 Beta2
Mapping documents:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel" assembly="Monitor.MktgWorksite.BLL">
<class name="NVariable" lazy="false" table="dbo.NVariable">
<id type="Int32" column="NVariableId" name="Id" unsaved-value="0">
<generator class="identity"/>
</id>
<discriminator column="VariableType" />
<version name="Version" type="Int32"/>
<many-to-one name="m_dataset" class="NDataset" access="field">
<column name="NDatasetId" not-null="true" unique-key="VariableName"/>
</many-to-one>
<many-to-one
name="m_category"
access="field"
class="NVariableCategory"
not-null="false"
column="NVariableCategoryId"/>
<property name="Name">
<column name="Name" not-null="true" unique-key="VariableName"/>
</property>
<property name="Label" not-null="true"/>
<property name="Description" not-null="false"/>
<property name="Order" column="VariableOrder" not-null="true"/>
<subclass name="NUploadedVariable`1[System.Double]" discriminator-value="1" lazy="false">
<property name="m_isDiscrete" not-null="false" type="boolean" access="field" column="IsDiscrete"/>
<property name="m_defaultCalculationType" access="field" column="DefaultCalculationType"/>
<property name="SerializedValues" not-null="false" column="VariableValues" length="1073741823"/>
<set name="m_data" access="field" lazy="true" check="false">
<key column="NVariableId"/>
<one-to-many class="NDataVariableData`1[System.Double]"/>
</set>
</subclass>
<subclass name="NUploadedVariable`1[System.String]" discriminator-value="2" lazy="false">
<property name="m_isDiscrete" not-null="false" type="boolean" access="field" column="IsDiscrete"/>
<property name="m_defaultCalculationType" access="field" column="DefaultCalculationType"/>
<property name="SerializedValues" not-null="false" column="VariableValues" length="1073741823"/>
<component name="m_data" access="field" class="NDataVariableData`1[System.String]">
<property name="m_data" access="field" type="Serializable" column="Data" length="1073741823"/>
<property name="EncodedMin"/>
<property name="EncodedMax"/>
<property name="m_numUniqueValues" access="field" type="int" column="NumUniqueValues"/>
</component>
</subclass>
<subclass name="NConditionalUDV" discriminator-value="3" lazy="false">
<property name="m_defaultCalculationType" access="field" column="DefaultCalculationType"/>
<property name="SerializedValues" not-null="false" column="VariableValues" length="1073741823"/>
<set name="m_data" access="field" lazy="true" check="false">
<key column="NVariableId"/>
<one-to-many class="NDataVariableData`1[System.Double]"/>
</set>
<set name="m_precedentVariables" access="field" table="dbo.NVariableDependency">
<key column="DependentVariableId"/>
<many-to-many class="NVariable" column="PrecedentVariableId"/>
</set>
</subclass>
<subclass name="NRegroupingUDV" discriminator-value="7" lazy="false">
<property name="m_defaultCalculationType" access="field" column="DefaultCalculationType"/>
<property name="SerializedValues" not-null="false" column="VariableValues" length="1073741823"/>
<set name="m_data" access="field" lazy="true" check="false">
<key column="NVariableId"/>
<one-to-many class="NDataVariableData`1[System.Double]"/>
</set>
<set name="m_precedentVariables" access="field" table="dbo.NVariableDependency">
<key column="DependentVariableId"/>
<many-to-many class="NVariable" column="PrecedentVariableId"/>
</set>
</subclass>
<subclass name="NRegroupingOfContinuousUDV" discriminator-value="8" lazy="false">
<property name="m_defaultCalculationType" access="field" column="DefaultCalculationType"/>
<property name="SerializedValues" not-null="false" column="VariableValues" length="1073741823"/>
<set name="m_data" access="field" lazy="true" check="false">
<key column="NVariableId"/>
<one-to-many class="NDataVariableData`1[System.Double]"/>
</set>
<set name="m_precedentVariables" access="field" table="dbo.NVariableDependency">
<key column="DependentVariableId"/>
<many-to-many class="NVariable" column="PrecedentVariableId"/>
</set>
</subclass>
<subclass name="NMathematicalUDV" discriminator-value="4" lazy="false">
<property name="m_defaultCalculationType" access="field" column="DefaultCalculationType"/>
<property name="m_formula" access="field" length="4000" column="Formula"/>
<set name="m_data" access="field" lazy="true" check="false">
<key column="NVariableId"/>
<one-to-many class="NDataVariableData`1[System.Double]"/>
</set>
<set name="m_precedentVariables" access="field" table="dbo.NVariableDependency">
<key column="DependentVariableId"/>
<many-to-many class="NVariable" column="PrecedentVariableId"/>
</set>
</subclass>
<subclass name="NDichotomousMRV" discriminator-value="5" lazy="false">
<property name="EncodedCountedValueCode"/>
<set name="m_precedentVariables" access="field" table="dbo.NVariableDependency">
<key column="DependentVariableId"/>
<many-to-many class="NVariable" column="PrecedentVariableId"/>
</set>
</subclass>
<subclass name="NCategoricalMRV" discriminator-value="6" lazy="false">
<set name="m_precedentVariables" access="field" table="dbo.NVariableDependency">
<key column="DependentVariableId"/>
<many-to-many class="NVariable" column="PrecedentVariableId"/>
</set>
</subclass>
</class>
<class name="NDataVariableData`1[System.Double]" lazy="true" table="dbo.NVariable">
<id type="Int32" column="NVariableId" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="m_data" access="field" type="Serializable" column="Data" length="1073741823"/>
<property name="EncodedMin"/>
<property name="EncodedMax"/>
<property name="m_numUniqueValues" access="field" type="int" column="NumUniqueValues"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
Full stack trace of any exception that occurs:
duplicate import: Double] refers to both Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel.NDataVariableData`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Monitor.MktgWorksite.BLL, Version=2.7.14.3, Culture=neutral, PublicKeyToken=null and Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel.NUploadedVariable`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Monitor.MktgWorksite.BLL, Version=2.7.14.3, Culture=neutral, PublicKeyToken=null (try using auto-import="false")
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: NHibernate.DuplicateMappingException: duplicate import: Double] refers to both Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel.NDataVariableData`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Monitor.MktgWorksite.BLL, Version=2.7.14.3, Culture=neutral, PublicKeyToken=null and Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel.NUploadedVariable`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Monitor.MktgWorksite.BLL, Version=2.7.14.3, Culture=neutral, PublicKeyToken=null (try using auto-import="false")
Source Error:
Line 182: {
Line 183: object existing = imports[rename];
Line 184: throw new DuplicateMappingException("duplicate import: " + rename +
Line 185: " refers to both " + className +
Line 186: " and " + existing +
Source File: C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Mappings.cs Line: 184
Stack Trace:
[DuplicateMappingException: duplicate import: Double] refers to both Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel.NDataVariableData`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Monitor.MktgWorksite.BLL, Version=2.7.14.3, Culture=neutral, PublicKeyToken=null and Monitor.MktgWorksite.BLL.Tools.MarketSight.DomainModel.NUploadedVariable`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Monitor.MktgWorksite.BLL, Version=2.7.14.3, Culture=neutral, PublicKeyToken=null (try using auto-import="false")]
NHibernate.Cfg.Mappings.AddImport(String className, String rename) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Mappings.cs:184
NHibernate.Cfg.HbmBinder.BindClass(XmlNode node, PersistentClass model, Mappings mappings) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\HbmBinder.cs:185
NHibernate.Cfg.HbmBinder.BindRootClass(XmlNode node, RootClass model, Mappings mappings) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\HbmBinder.cs:301
NHibernate.Cfg.HbmBinder.BindRoot(XmlDocument doc, Mappings mappings) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\HbmBinder.cs:1736
NHibernate.Cfg.Configuration.AddValidatedDocument(XmlDocument doc, String name) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:410
[MappingException: Could not compile the mapping document: Monitor.MktgWorksite.BLL.Tools.MarketSight.NDataset.NVariable.hbm.xml]
NHibernate.Cfg.Configuration.LogAndThrow(MappingException me) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:249
NHibernate.Cfg.Configuration.AddValidatedDocument(XmlDocument doc, String name) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:415
NHibernate.Cfg.Configuration.AddXmlReader(XmlTextReader hbmReader, String name) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:1575
NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:480
NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:517
NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly, Boolean skipOrdering) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:634
NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly) in C:\sandbox\MarketSight_P4_2006\NHibernate\src\Cfg\Configuration.cs:596
Monitor.MktgWorksite.BLL.NHibernateSupport.SingletonSessionFactory..ctor() in C:\sandbox\MarketSight_P4_2006\MktgWorksite\MktgWorksite.BLL\NHibernateSupport\SessionHandler.cs:141
Monitor.MktgWorksite.BLL.NHibernateSupport.Nested..cctor() in C:\sandbox\MarketSight_P4_2006\MktgWorksite\MktgWorksite.BLL\NHibernateSupport\SessionHandler.cs:169
[TypeInitializationException: The type initializer for 'Nested' threw an exception.]
Monitor.MktgWorksite.BLL.NHibernateSupport.SingletonSessionFactory.get_Configuration() in C:\sandbox\MarketSight_P4_2006\MktgWorksite\MktgWorksite.BLL\NHibernateSupport\SessionHandler.cs:149
Monitor.MktgWorksite.BLL.NHibernateSupport.SessionHandler.get_Configuration() in C:\sandbox\MarketSight_P4_2006\MktgWorksite\MktgWorksite.BLL\NHibernateSupport\SessionHandler.cs:124
Monitor.MktgWorksite.Web.Tools.MarketSight.UnitTest.NHibernateTest.GenerateDDL_Click(Object sender, EventArgs e) in C:\sandbox\MarketSight_P4_2006\MktgWorksite\MktgWorksite.Web.UI\Tools\MarketSight\UnitTest\NHibernateTest.aspx.cs:47
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +96
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +117
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +31
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +32
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +72
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3838
Name and version of the database you are using:
MS SQL/Server 2000