I've tried playing with this extensively. I've tried searching google and can't seem to find anything pointing how to do this.
Scenario is i have a class A with a ID, class B extends class A... simple inheritance. In the database class A is a seperate table as class B... A has a auto generated ID... B has a foreign key value ID pointing to A
If i remove the joined-subclass and make Character a property of Player instead of it being inherited i have no problems at all and i can get it to work just fine. I decided i didn't want that design and i want player to inherit character... but character will be inherited from other things as well like NPC class etc...
EDIT: I wanted to point out that if i added another field to the Player table and call it say ID2 and marked it as a identity column, then change the xml to reflect it, i still get the same dupe/key error. So it doesn't have anything to do with both xml files containing a ID field...
heres the code illustrating it.
Hibernate version: 2.0.0.Alpha1
Mapping documents:
Character.hbm.xml
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Convergence.Libraries.Core"
namespace="Convergence.Libraries.Core.Entities">
<class name="Character" table="Character">
<id name="ID" column="ID" type="Int64">
<generator class="identity"/>
</id>
<property name="Name" type="String" length="50" column="Name"/>
<property name="Health" type="Int32" column="Health"/>
</class>
</hibernate-mapping>
Player.hbm.xml
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Convergence.Libraries.Core"
namespace="Convergence.Libraries.Core.Entities">
<class name="Player" table="Player" lazy="false">
<id name="ID" column="ID" type="Int64">
<generator class="assigned"/>
</id>
<property name="Password" type="String" length="50" column="Password" not-null="true" />
<joined-subclass name="Character" table="Character">
<key column="ID"/>
</joined-subclass>
</class>
</hibernate-mapping>
Character.cs
Code:
namespace Convergence.Libraries.Core.Entities
{
public class Character
{
public Character() { }
public Character(string name)
{
Name = name;
}
public virtual long ID { get; private set; }
public virtual string Name { get; private set; }
public virtual string Health { get; private set; }
}
}
Player.cs
Code:
using NHibernate;
namespace Convergence.Libraries.Core.Entities
{
public class Player : Character
{
public virtual string Password { get; set; }
public static Player GetById(long id)
{
using (ISession session = Database.GetSession())
return session.Load<Player>(id);
}
public static void Save(Player p)
{
using (ISession session = Database.GetSession())
Save(p, session);
}
public static void Save(Player p, ISession session)
{
session.Save(p);
}
}
}
Full stack trace of any exception that occurs:Failure line
Code:
cfg.AddAssembly("Convergence.Libraries.Core"); //Could not compile the mapping document: Convergence.Libraries.Core.Entities.Character.hbm.xml
Error (Inner Exception)
Code:
NHibernate.DuplicateMappingException: Duplicate class/entity mapping Convergence.Libraries.Core.Entities.Character
at NHibernate.Cfg.Mappings.AddClass(PersistentClass persistentClass)
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(XmlNode node, HbmClass classSchema)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(XmlNode parentNode)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(XmlNode node)
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc)
Stack Trace
Code:
at NHibernate.Cfg.Configuration.LogAndThrow(Exception exception)
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc)
at NHibernate.Cfg.Configuration.ProcessMappingsQueue()
at NHibernate.Cfg.Configuration.AddDocumentThroughQueue(NamedXmlDocument document)
at NHibernate.Cfg.Configuration.AddXmlReader(XmlReader hbmReader, String name)
at NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name)
at NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly)
at NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly)
at NHibernate.Cfg.Configuration.AddAssembly(String assemblyName)
at Convergence.Libraries.Core.Database.Initialize() in D:\\source\\.NET\\Convergence\\Libraries\\Convergence.Libraries.Framework\\Database.cs:line 30
Name and version of the database you are using: MSSQL 2005