NHibernate,保存IDictionary:TransientObjectException

时间:2009-07-09 12:09:45

标签: c# nhibernate nhibernate-mapping instance transient

在我的类Case中,我有一个IDictionary,其中Entity(一个类)作为键,Roles(一个枚举)作为值。当试图保存Case的新实例(非持久化)时,IDictionary充满了Entity的新实例,我得到以下错误:

  

NHibernate.TransientObjectException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。类型:实体

这些是类(角色是枚举):

public class Case
{
    public Case { EntityCollection = new Dictionary<Entity, Roles>(); }
    public virtual int Id { get; set; }
    public virtual IDictionary<Entity, Roles> EntityCollection { get; set; }
}

public class Entity
{
    public virtual int Id { get; set; }
}

映射如下:

<class name="Case" table="[Case]">
    <id name="Id" column="Id" type="Int32" unsaved-value="any">
        <generator class="hilo"/>
    </id>
    <map name="EntityCollection" table="CaseEntityRoles" 
     cascade="save-update" lazy="false" inverse="false">
        <key column="CaseId" />
        <index-many-to-many class="Entity" 
         column="EntityId" />
        <element column="Roles" type="Roles" not-null="true" />
    </map>
</class>

<class name="Entity" table="[Entity]">
    <id name="Id" column="Id" type="Int32" unsaved-value="0">
        <generator class="hilo"/>
    </id>
</class>

测试代码示例:

[Test]
public void Can_add_new_case()
{
    var newCase = new Case();
    newCase.EntityCollection.Add(new Entity(), Roles.Role1);
    newCase.EntityCollection.Add(new Entity(), Roles.Role2);

    /* At which point I try to persist newCase and get an exception */
}

在testcode中,newCase-instance是持久化的,但新实体不是。我尝试过很多不同的东西,例如添加&lt; version&gt;标记到实体并乱用未保存的值,但似乎没有任何帮助。正如你从映射中看到的那样,我确实有cascade =“save-update”。 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

在您尝试保留Case之前,我认为您需要先保留Case引用的Entity对象。我有一个类似的问题,我这样解决了。例如,使用Rhino NHRepository:

[Test]
public void Can_add_new_case()
{
    var newCase = new Case();
    var entity1 = new Entity();
    var entity2 = new Entity();
    newCase.EntityCollection.Add(entity1, Roles.Role1);
    newCase.EntityCollection.Add(entity2, Roles.Role2);

    Rhino.Commons.NHRepository<Entity> entityRepository = new NHRepository<Entity>();
    Rhino.Commons.NHRepository<Case> caseRepository = new NHRepository<Case>();

    using (UnitOfWork.Start())
    {
        entityRepository.SaveOrUpdate(entity1);
        entityRepository.SaveOrUpdate(entity2);
        caseRepository.SaveOrUpdate(newCase);
    }
}

答案 1 :(得分:0)

如果将inverse设置为true会发生什么?

我不知道这是否会解决你的问题...

您可以做的是使用Repository模式,并创建一个'CaseRepository'类。 在该存储库中,您将拥有一个Save方法,该方法将保存给定的Case。 在该save方法中,您可以遍历给定Case的所有实体,并为每个Entity显式调用'SaveOrUpdate'。

我也想知道你为什么在这个问题上使用词典?