我的Oracle数据库中的父对象和子对象BOOKLET和DEMOGRAPHICS_INFO在我的数据层中映射如下:
public BookletMapping()
{
Table("BOOKLET");
Id(x => x.Id, m => m.Column("ID");
...
ManyToOne(x => x.DemographicsInfo, m => m.Column("DEMOGRAPHICS_INFO_ID"));
}
public DemographicsInfoMapping()
{
Table("DEMOGRAPHICS_INFO");
Id(x => x.Id, m => m.Column("ID");
...
}
我故意将DemographicsInfo关系遗漏给Booklet,因为我不需要遍历我的实体那个方向。 ManyToOne关系实际上是一对一的。
我已经编写了一个测试,以确保我可以创建DemographicsInfo并立即将其分配给其父Booklet,如下所示:
[Test]
public void ShouldSaveCorrectEntity()
{
var booklet = _unitOfWork.Get<Booklet>(4);
var demInfo = new DemographicsInfo();
_unitOfWork.Insert(demInfo);
booklet.DemographicsInfo = demInfo;
_unitOfWork.Save();
demInfo.Id.ShouldNotEqual(0);
}
当我调用Save()时,我得到以下异常:
{"ORA-02291: integrity constraint (<schema>.BOOKLET_DEMOGRAPHICS_INFO_FK1) violated - parent key not found\n"}
这是因为在插入()时没有给demInfo对象一个Id。我的Insert实现如下所示:
public void Insert<T>(T entity)
{
using (var transaction = _session.BeginTransaction())
{
_session.Save(objectToSave);
_session.Flush();
transaction.Commit();
}
}
其中_session是NHibernate ISession。因为我已经保存了新实体(它成功保存)并刷新了我的会话,我希望我的demInfo变量有一个Id,但它仍然是0,这是我尝试保存父对象时的外键违规。我在这里俯瞰一步吗?我是否应重新考虑将新子项添加到现有父项的模式?
答案 0 :(得分:0)
我已经解决了我的问题。事实证明,使用Sequences for Id列值并使用行插入触发器填充它们的Oracle约定不允许NHibernate在持久化实体时学习Id。我在我的Id地图中添加了一个序列生成器,Insert()现在在保存后更新我的瞬态实体上的Id,这样我就可以将DemographicsInfo分配给我的Booklet.DemographicsInfo。
Id(x => x.Id, m =>
{
m.Column("ID");
m.Generator(Generators.Sequence, a => a.Params(new { sequence = "SEQ_TABLE_ID" }));
});
现在我的测试没有例外。