问题
In my project all of entities have composite primary keys [systemId as long, deviceId as long, id as long]. Values filled manualy before I save the entity. I'm using "code first" approach and to provide simplicity references NHibernate.Mapping.Attributes extension to define schema with attributes just like in Java based Hibernate.
All entities have an abstract base type which provides shared properties and functionality:
[Serializable]
public abstract class EntityBase
{
[CompositeId(0, Name = "id", ClassType = typeof(EntityId))]
[KeyProperty(1, Name = "systemId", Column = "restId")]
[KeyProperty(2, Name = "deviceId", Column = "deviceId")]
[KeyProperty(3, Name = "id", Column = "id")]
private EntityId id = new EntityId(); // this is a component, see below
[Property(Column = "isDeleted", NotNull = true)]
private bool deleted = false;
public EntityId Id
{
get { return id; }
set { id = value; }
}
public bool Deleted
{
get { return deleted; }
set { deleted = value; }
}
}
Behind the composite id there is a component, which represent the complex primary key:
[Serializable]
[Component]
public class EntityId
{
[Property(Column = "restId", NotNull = true)]
private long systemId = 0;
[Property(NotNull = true)]
private long deviceId = 0;
[Property(NotNull = true)]
private long id = 0;
public long SystemId
{
get { return systemId; }
set { systemId = value; }
}
public long DeviceId
{
get { return deviceId; }
set { deviceId = value; }
}
public long Id
{
get { return id; }
set { id = value; }
}
}
I definied two entities called OTMList and OTMItem which have bi-directional OneToMany and ManyToOne associations to each other.
[Serializable]
[Class]
public class OTMList : EntityBase
{
[List(0, Cascade = "none", Generic = true, Lazy = CollectionLazy.True)]
[Key(1, Column = "id")]
[Index(2, Column = "id")]
[OneToMany(3, NotFound = NotFoundMode.Exception, ClassType = typeof(OTMItem))]
private IList<OTMItem> otmItems = new List<OTMItem>();
public IList<OTMItem> OTMItems
{
get { return otmItems; }
set { otmItems = value; }
}
}
[Serializable]
[Class]
public class OTMItem : EntityBase
{
[ManyToOne(0, Name = "otmList", ClassType = typeof(OTMList), Column = "OTMListId", Cascade = "none", Lazy = Laziness.Proxy)]
private OTMList otmList = null;
public OTMList OTMList
{
get { return otmList; }
set { otmList = value; }
}
}
The hibernate mapping xml file contains the following information:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping default-access="field" auto-import="true" assembly="NHibernateTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="urn:nhibernate-mapping-2.2">
<class name="NHibernateTest.ListTest.OTM.OTMList, NHibernateTest">
<composite-id class="NHibernateTest.Domain.EntityId, NHibernateTest" name="id">
<key-property name="systemId" column="restId" />
<key-property name="deviceId" column="deviceId" />
<key-property name="id" column="id" />
</composite-id>
<property name="deleted" column="isDeleted" not-null="true" />
<list name="otmItems" lazy="true" cascade="none" generic="true">
<key column="id" />
<index column="id" />
<one-to-many class="NHibernateTest.ListTest.OTM.OTMItem, NHibernateTest" not-found="exception" />
</list>
</class>
<class name="NHibernateTest.ListTest.OTM.OTMItem, NHibernateTest">
<composite-id class="NHibernateTest.Domain.EntityId, NHibernateTest" name="id">
<key-property name="systemId" column="restId" />
<key-property name="deviceId" column="deviceId" />
<key-property name="id" column="id" />
</composite-id>
<property name="deleted" column="isDeleted" not-null="true" />
<many-to-one name="otmList" class="NHibernateTest.ListTest.OTM.OTMList, NHibernateTest" column="OTMListId" cascade="none" lazy="proxy" />
</class>
</hibernate-mapping>
When I validate the schema with SchemaValidator of the NHibernate I get the following exception:
Foreign key (FKF208BF0B9A2FCB3:OTMItem [OTMListId])) must have same number of columns as the referenced primary key (OTMList [restId, deviceId, id])
The problem are the same too when I try to create uni-directional ManyToOne or bi/uni-directional ManyToMany associations.
Somebody can help me please?
The full source code available here:
NHibernateTest source code
回答1:
The problem is solved, check this out:
http://jzo001.wordpress.com/category/nhibernate/
来源:https://stackoverflow.com/questions/10266347/nhibernate-composite-id-mapping-issue-bi-uni-directional-onetomany-manytoone-a