在NHIBERNATE中创建和检索相关的映射
-
10-10-2019 - |
题
说我有两个持久的课程 Cat
和 Hat
. 。让我们想象,两者之间的关系在双向一对多,因为在猫中可以有许多不同的帽子,我们可以在两个方向上穿越映射。为了在每个类的实例之间建立关联,我应该能够并纠正我,如果我错了,请执行以下操作:
Cat whiskers = new Cat();
Hat redHat = new Hat();
redHat.Id = 1; // normally assigned by generator but this makes example more explicit
whiskers.Hats.Add(redHat);
catService.Save(whiskers);
hatService.Save(redHat);
考虑到这一点,我是否应该通过执行以下操作来检索与Redhat相关的猫?
Hat hat = hatService.FindById(1); // redHat has Id 1
Cat cat = hat.Cat; // cat should be whiskers
不幸的是,当我尝试使用这种技术时,CAT在最后一行中作为无效对象。我猜想我在Cat.hbm.xml的一对一映射中缺少一些东西,或者至少我希望这很简单。这就是目前的样子:
<set name="Hats" inverse="true">
<key column="Id"/>
<one-to-many class="Hat"/>
</set>
我没有hat.hbm.xml的映射,因为添加一个导致“重复映射”错误。我读了冬眠 文档 在关联映射上,但仍然无法正常工作。我究竟做错了什么?
完成下面的映射文件:
cat.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Domain"
namespace="Domain">
<class name="Cat" table="cats" lazy="true">
<id name="Id">
<generator class="increment" />
</id>
<property name="Name" />
<set name="Hats" inverse="true">
<key column="Id"/>
<one-to-many class="Hat"/>
</set>
</class>
</hibernate-mapping>
hat.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Domain"
namespace="Domain">
<class name="Hat" table="hats" lazy="true">
<id name="Id">
<generator class="increment" />
</id>
</class>
</hibernate-mapping>
编辑
我相信问题是我没有初始化 ISet<Hat>
在猫类中的价值。但是,我遇到了一个新问题。当我尝试访问关联时,我会收到此错误:
Could not initialize proxy - no Session.
我认为,如果我在dao中创建了一种方法,可以在这样的会话中包装它,可以很容易地避免使用:
public Cat GetRelatedCat(Hat hat)
{
Cat cat;
using (ISession session = HibernateUtil.GetSessionFactory().OpenSession())
{
cat = hat.Cat;
}
return cat;
}
这会产生相同的“无会话”错误。我很难过。
解决方案 2
我通过创建一个SessionManager解决了问题,该会议管理器使我能够打开会话,执行任何交易并访问Singleton中的任何集合代理,然后关闭会话。
其他提示
您需要在hat.hbm中添加多一对一的条目。我认为应该工作。
然后,您必须设置协会的两面
whiskers.hats.add(redhat);
redhat.cat =晶须;
我认为这应该使您的样本起作用。
您的“无会话”问题的原因是,该集合代理仅与与之创建的会话一起使用。因此,在您的示例中,它仅适用于创建您的HAT实例的会话。可以将代理与另一个会话联系起来,但通常不推荐,因为它对交易边界和数据一致性具有复杂的影响。