说我有两个持久的课程 CatHat. 。让我们想象,两者之间的关系在双向一对多,因为在猫中可以有许多不同的帽子,我们可以在两个方向上穿越映射。为了在每个类的实例之间建立关联,我应该能够并纠正我,如果我错了,请执行以下操作:

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中的任何集合代理,然后关闭会话。

其他提示

  1. 您需要在hat.hbm中添加多一对一的条目。我认为应该工作。

  2. 然后,您必须设置协会的两面

    whiskers.hats.add(redhat);

    redhat.cat =晶须;

我认为这应该使您的样本起作用。

您的“无会话”问题的原因是,该集合代理仅与与之创建的会话一起使用。因此,在您的示例中,它仅适用于创建您的HAT实例的会话。可以将代理与另一个会话联系起来,但通常不推荐,因为它对交易边界和数据一致性具有复杂的影响。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top