2011-01-12 60 views
0

假设我有两个持久类CatHat。让我们设想两者之间的关系是双向的一对多的关系,因为猫可以有许多不同的帽子,我们可以在两个方向上遍历映射。为了创建每个类的实例之间的关联,我应该能够和纠正我,如果我错了,请执行下列操作:在NHibernate中创建和检索关联的映射

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关联的Cat?

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中没有映射,因为添加一个会导致“重复映射”错误。我在关联映射中读到Hibernate documentation,但仍无法正常工作。我究竟做错了什么?

完全映射文件如下:

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> 

编辑

我认为问题在于我没有初始化Cat类中的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; 
} 

这会产生相同的“无会话”错误。我很难过。

+1

你能显示你的完整映射文件吗? – MarioH 2011-01-12 09:41:08

+0

@MarioH:我已经用完整的映射文件更新了这篇文章。 – 2011-01-13 00:31:51

回答

0

我通过创建一个SessionManager解决了这个问题,它允许我打开Session,执行任何事务并访问Session单例内的任何集合代理,然后关闭Session。

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

  2. 然后你要设置的关联

    whiskers.Hats.Add(REDHAT)两侧;

    redHat.Cat =胡须;

我认为这应该会使您的示例工作。

您的“无会话”问题的原因是,集合代理仅适用于创建它的会话。因此,在您的示例中,它仅适用于创建您的Hat实例的会话。可以将代理连接到另一个会话,但通常不推荐这样做,因为它对事务边界和数据一致性有复杂的影响。