2009-07-09 2 views
1

В моем классе Case У меня есть IDictionary с Entity (класс) в качестве ключа и Роли (enum) как значение. При попытке сохранить новый экземпляр (не сохранилась) в случае, когда IDictionary наполнен новыми экземплярами сущностей я получаю следующее сообщение об ошибке:NHibernate, сохранение IDictionary: TransientObjectException

NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing. Type: Entity

Эти классы (Роли является перечисление):

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-экземпляр сохраняется, но новые объекты не являются. Я пробовал много разных вещей, например добавление тега < version> в Entity и беспорядок с несохраненным значением, но ничего не помогает. И как вы можете видеть из сопоставления, у меня есть cascade = "save-update". Любые идеи?

ответ

1

Я думаю, что вам нужно перенести объекты 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); 
    } 
} 
+1

Да, это в значительной степени то, что я и сделал. Жаль, что он не обрабатывается NHibernate автоматически. Если кто-нибудь знает какие-либо другие решения (или узнайте, когда эта ошибка, если это ошибка, будет исправлена), пожалуйста, сообщите, но до тех пор я предполагаю, что я должен принять это как необходимое решение. – 2009-08-12 08:55:44

0

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

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

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

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

+0

Если я устанавливаю инверсию в true, я не получаю исключения, но сущности по-прежнему не сохраняются. Я действительно использую общий класс Repository с методом Save, но я не хотел писать дополнительный код для этого, если NHibernate смог сделать это для меня, если бы правильно отобразил его. Если у меня нет другого выбора, это, вероятно, будет тем, что я должен сделать. Я использую словарь, потому что я хотел только сохранить одно и то же Entity один раз для каждого случая (именно поэтому я использую их как ключ). И идея заключалась в том, что если у одного Entity есть много ролей, я могу просто использовать Flags-enum. Если это станет проблематичным, мне, вероятно, придется пересмотреть мое решение. – 2009-07-09 12:32:58

Смежные вопросы