稍微改变了我的映射( see my other question about cascade-delete for reasons)后,我尝试插入一个全新的对象及其所有子类。
在此之后出现了另一个问题,即将密钥插入数据库的问题。情况如下:
我有一个包含2层子类的对象,这两个都是一个集合。
让我们调用对象Parent,这个对象有一个子集合,这个集合中的每个enitity都有自己的enitities集合。其映射如下。
家长对其<set>
<!--Parent-->
<set name="Collection"
table="Table"
cascade="all-delete-orphan"
batch-size="15"
inverse="true">
<key column="ParentID"/>
<one-to-many class="CollectionObject,CollectionObject-ns"/>
</set
CollectionObject的映射
<id name="ID" column="ID">
<generator class="native"/>
</id>
<!-- property mappings-->
<property name="ParentID" column="ParentID" not-null="true"/>
<!--collection mapping-->
<set name="Collection"
table="Table"
cascade="all-delete-orphan"
inverse="true"
batch-size="15">
<key column="ChildID"/>
<one-to-many class="CollectionObject,CollectionObject-ns"/>
</set>
第二个集合中对象的映射映射与上面的类似。 设想的场景是,我保存Parent,这将触发子类/集合的保存。
e.g。我有ID为1的Parent,Parent有1个集合,此集合有1个集合。
所以我保存Parent,parent从数据库中获取一个ID(本机sql标识)。现在第一个集合应该让它的ParentID属性填充Parent从数据库中获得的ID。并且该集合的集合应该使其ChildID以Child与其获取其ID相同的方式填充Child从数据库获取的ID。
现在发生的事情是(我在NHProf中检查了创建的SQL)所有东西都被插入,带有自己的ID,但是集合没有让他们的keycolumn填充其父类的ID。 (相反它只是插入0)
所以我的问题归结为,我忘了添加到我的映射中导致了什么?关键专栏是否做了我认为应该做的事情?
如果我忘了在这里添加任何内容,请说出来。我很乐意提供更多信息。
更新
我认为问题可能与没有<many-to-one>
标签的孩子有关。所以我试着将其中一个添加到第一个子映射中。我想出了这个
<many-to-one name="ParentID"
class="Parent,Parent-ns"
column="ParentID"
not-null="true"/>
但是,此设置会给我以下错误。
Exception occurred getter of Parent.ParentID
{"Object does not match target type."}
可悲的是,这个错误并没有给我任何关于从哪里继续的想法。
答案 0 :(得分:1)
我认为如果您能向我们展示您的课程将会有所帮助。您是否检查过您的Parent类确实具有Parent类型的ParentID属性,我还假设您已经删除了
<property name="ParentID" column="ParentID" not-null="true"/>
从您的映射中将其替换为多对一?最后,如果您希望子对象具有子对象的集合,那么子对象也需要多对一
<many-to-one name="CollectionObjectParent"
class="CollectionObject,CollectionObject-ns"
column="ChildID"
not-null="true"/>
答案 1 :(得分:0)
可悲的是,在玩过映射并阅读半数互联网之后,我无法解决这个问题。
问题在于我无法进入<Document>
从数据库<generator class="native"/>
获取密钥的情况,并在此之后将此密钥插入其基础类的foreignkey属性中,一个session.Save()
电话。
e.g。我喜欢session.Save(document)
- *检测到新文件 - *获得新身份
- *文件有子类,带有外键!
- *将标识插入指定的外键属性(猜猜这就是问题所在)
并对所有基础类重复此操作。
然而,我确实提出了一个解决方法(有史以来最丑陋的代码,但它完成了工作)我真的没有真正分享这个糟糕的代码,但它可能会帮助人们在这里阅读。我还没有放弃以正确的方式解决这个问题,但目前还有这个问题。 Stil向更好的方向轻推。
传入的垃圾代码!
public void InsertDocument(Document document)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
try
{
IDocument document2 = new Document();
document2.Bodyregels = document.Bodyregels;
//for making the query a little neater
document.Bodyregels = null;
//lets get the elusive identity
session.Save(document);
session.Flush();
//reattach subclass and enter the id explicitly
document.Bodyregels = document2.Bodyregels;
foreach (DocumentBodyregel dbr in document.Bodyregels)
{
dbr.DocumentID = document.DocumentID;
}
//save it again, now with filled FK
session.Save(document);
session.Flush();
//now save the final subclass with FK's
foreach (DocumentBodyregel dbr in document.Bodyregels)
{
foreach (DocumentBodyregelWaarde dbrw in dbr.Waardes)
{
dbrw.RegelID = dbr.ID;
dbrw.DocumentID = document.DocumentID;
}
}
//and save the entire thing again (now with FK's)
session.Save(document);
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
throw e;
}
}
}
}