I have a self referencing entity named Category. A category may have one or more child categories. A category may also have no childs.
I have made the entity and mapping but I keep getting this exception.
NHibernate.TransientObjectException : object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave.
Am I doing something wrong with the mapping part?
Is it possible to save all Parent and Child objects at once?
Any help would be appreciated.
Following is the Code
POCO
public class Category
{
private ICollection<Topic> _topics;
private ICollection<Category> _childCategory;
private ICollection<Media> _media;
private Category _parentCategory;
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual bool IsActive { get; set; }
public virtual Category ParentCategory
{
get { return _parentCategory ?? (_parentCategory = new Category()); }
protected set { _parentCategory = value; }
}
public virtual ICollection<Category> ChildCategory
{
get { return _childCategory ?? (_childCategory = new List<Category>()); }
protected set { _childCategory = value; }
}
public virtual void AddChild(Category childCategory)
{
childCategory.ParentCategory = this;
}
}
Mapping
public class CategoryMapping : IAutoMappingOverride<Category>
{
public void Override(AutoMapping<Category> mapping)
{
mapping.Map(c => c.Name).Length(30);
mapping.Map(c => c.Description).Length(160);
mapping.References(x => x.ParentCategory)
.Cascade.None()
.Column("ParentCategoryId");
mapping.HasMany(x => x.ChildCategory)
.Inverse().Cascade.All()
.KeyColumn("ParentCategoryId");
}
}
Test I am creating parent and child categories and trying to save all of them at once.
public void CanSaveAllNewObjectGraphFromCategory() {
#region Categories and Child
var categories = new sq.Category()
{
Description = "Category1",
IsActive = true,
Name = "Categoy1"
};
var childCat = new List<sq.Category>() {
new sq.Category(){
Description = "ChildCategory1",
IsActive = true,
Name = "CCategoy1"
},
new sq.Category(){
Description = "ChildCategory2",
IsActive = true,
Name = "CCategoy2"
}
};
foreach (var item in childCat)
{
categories.AddChild(item);
}
#endregion
using (var tx = _session.BeginTransaction())
{
_catRepo.AddNewCategory(categories);
tx.Commit(); // Error occurs when commit is executed.
}
}
Your error message gave you two options:
The first option is straightforward: simply save each instance before commiting the transaction
using (var tx = _session.BeginTransaction())
{
foreach(var category in categories)
{
_session.SaveOrUpdate(category);
}
_catRepo.AddNewCategory(categories);
tx.Commit();
}