NHibernate giving me problems when saving new item.

Topics: Developer Forum, Project Management Forum, User Forum
Nov 22, 2008 at 10:05 PM
Message = "object references an unsaved transient instance - save the transient instance before flushing: N2.ContentItem"

StackTrace = "   at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)\r\n   at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session)\r\n   at NHibernate.Type.ManyToO...

I'm not familiar with NHibernate so I don't know the first thing to look at. What do you think?





StackTrace = "   at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)\r\n   at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session)\r\n   at NHibernate.Type.ManyToO...
Coordinator
Nov 23, 2008 at 8:55 AM
In my experience this it typically due to not saving the entities in the "correct" order. There is a bug in 1.4.3.1 that causes this.

If there is a link to a file in the file system there is a link tracker that adds a link to the file. However these are generated and shouldn't be referenced.

Here's a couple of examples where the exception would happen:

- parent (new)
    - child (new)

save(child) // we must save the parent before we can save child

or:

- item
- item2 (new)

item["SomeProperty"] = item2

save(item) // must save item2 before we can save an association to it


Jan 25, 2009 at 4:34 PM
Hi,

I'm getting the exception
$exception    {"object references an unsaved transient instance - save the transient instance before flushing: N2.ContentItem"}    System.Exception {NHibernate.TransientObjectException}
when trying to automatically add children to an item on the OnItemSaving event.

an excerpt from my code, error on the bold part.

protected virtual void OnItemSaving(ContentItem item, CancellableItemEventArgs e)
    {
        //custom handling which item can and which cannot be deleted
        if (item.GetType() == typeof(Week))
        {
            if (item.Children.Count == 0)
            {
                IEngine engine = Context.Current;
                ContentItem newChild = engine.Definitions.CreateInstance<WeekChild>(item);
                newChild .Title = "Opties";
                newChild .Name = "opties";               
                engine.Persister.Save(newChild );
                item.Children.Add(newChild );
            }
       }
}

It obviously is the result of the sequence of saving items...
item has ID 0 all the time.
The problem is...it worked before...and I do not know when...
Is there perhaps an other solution?
Jan 25, 2009 at 7:49 PM
Hey,

The issue is that your item has not been saved and you trying to save the child. So your code should look like this

protected virtual void OnItemSaving(ContentItem item, CancellableItemEventArgs e)
    {
        //custom handling which item can and which cannot be deleted
        if (item.GetType() == typeof(Week))
        {
            if (item.Children.Count == 0)
            {
                IEngine engine = Context.Current;
                ContentItem newChild = engine.Definitions.CreateInstance<WeekChild>(item);
                newChild .Title = "Opties";
                newChild .Name = "opties";               
                item.Children.Add(newChild );
            }
       }
}

when the the item is saves it also has to save any unsaved children

One thing to note is that this event is fired before the item is saved

Hope this helps
Elizabeth
Jan 25, 2009 at 9:09 PM
Thanks Elizabeth!
That was the trick. I guess I had it like that once (it shouldn't have worked any other way).
Thanks!

Martijn