NHibernate, сохранение IDictionary: TransientObjectException - PullRequest
1 голос
/ 09 июля 2009

В моем классе 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 */
}

В тестовом коде экземпляр newCase сохраняется, а новые объекты - нет. Я пробовал много разных вещей, таких как добавление тега <<code>version> в Entity и возня с несохраненным значением, но, похоже, ничего не помогло. И, как вы можете видеть из сопоставления, у меня есть cascade = "save-update". Есть идеи?

Ответы [ 2 ]

1 голос
/ 10 августа 2009

Я думаю, вам нужно сохранить объекты Entity, на которые ссылается Case, прежде чем пытаться сохранить Case. У меня была похожая проблема, которую я решил таким образом. Например, используя 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);
    }
}
0 голосов
/ 09 июля 2009

Что произойдет, если вы установите обратное значение true?

Я не знаю, решит ли это вашу проблему ...

Что вы можете сделать, так это использовать шаблон Repository и создать класс CaseRepository. В этом хранилище у вас будет метод Save, который будет сохранять заданный случай. В этом методе сохранения вы можете зациклить все сущности для данного Case и явно вызвать 'SaveOrUpdate' для каждой сущности.

Мне также интересно, почему вы используете словарь для этой проблемы?

...