4

I'm using nHibernate and trying to add some master-detail data. The database diagram is attached here. Database diagram

The following is the code for adding a category along with two products:

//Category
namespace Sample.CustomerService.Domain
{

    public class Category {
        public Category() {
            Products = new List<Product>();
        }
        public virtual int CategoryID { get; set; }
        public virtual IList<Product> Products { get; set; }
        public virtual string Name { get; set; }
        public virtual string Unit { get; set; }

        public virtual void AddProduct(Product product)
        {
            Products.Add(product);
        }
    }
}

//CategoryMap
namespace Sample.CustomerService.Domain
{

    public class CategoryMap : ClassMap<Category> {

        public CategoryMap() {
            Table("Category");
            LazyLoad();
            Id(x => x.CategoryID).GeneratedBy.Identity().Column("CategoryID");
            Map(x => x.Name).Column("Name").Not.Nullable().Length(50);
            Map(x => x.Unit).Column("Unit").Not.Nullable().Length(3);
            HasMany(x => x.Products).KeyColumn("CategoryID");
        }
    }
}

//--------------------------------------------------------------------------------------------
//Product
namespace Sample.CustomerService.Domain
{

    public class Product {
        public Product() {
        }
        public virtual int ProductID { get; set; }
        public virtual Category Category { get; set; }
        public virtual string Name { get; set; }
        public virtual decimal UnitPrice { get; set; }

    }
}

//ProductMap
namespace Sample.CustomerService.Domain {


    public class ProductMap : ClassMap<Product> {

        public ProductMap() {
            Table("Product");
            LazyLoad();
            Id(x => x.ProductID).GeneratedBy.Identity().Column("ProductID");
            References(x => x.Category).Column("CategoryID");
            Map(x => x.Name).Column("Name").Not.Nullable().Length(50);
            Map(x => x.UnitPrice).Column("UnitPrice").Not.Nullable();
        }
    }
}

//----------------------------------------------------------------------------------------------
//Program
namespace WindowsHibernateTest
{
    public partial class TestClass : Form
    {
        public TestClass()
        {
            InitializeComponent();
            CreateNewProduct();
        }

        public void CreateNewProduct()
        {
            try
            {
                var sessionFactory = CreateSessionFactory();
                using (var session = sessionFactory.OpenSession())
                {
                    using (var sqlTrans = session.BeginTransaction())
                    {
                        Category newGold = new Category() { Name = "Gold", Unit = "GRM" };

                        Product ngOrn = new Product() { Name = "Bangles", UnitPrice = 1000.10M };
                        Product ogOrn = new Product() { Name = "Rings", UnitPrice = 2000.10M };

                        AddProductsToCategory(newGold, ngOrn, ogOrn);

                        session.SaveOrUpdate(newGold);

                        sqlTrans.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private static ISessionFactory CreateSessionFactory()
        {
            return Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.
                ConnectionString("Data Source=MyDB; Initial Catalog=NHibernateTest; Trusted_Connection=true;")).Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>()).BuildSessionFactory();

        }

        public static void AddProductsToCategory(Category category, params Product[] products)
        {
            foreach (var product in products)
            {
                category.AddProduct(product);
            }
        }

    }
}

In the line sqlTrans.Commit(), I'm getting the following error:

object references an unsaved transient instance - save the transient instance before flushing. Type: Sample.CustomerService.Domain.Product, Entity: Sample.CustomerService.Domain.Product

I've Googled for quite sometime and didn't get convincing solutions for this. I've tried this, this and this, but could not able to resolve this error. Please help me to resolve this error. Thanks in advance.

1
  • don't know if that is your problem but you need to change the add product method you got there: foreach (var product in products) { category.AddProduct(product); product.Category = category; } Commented Nov 8, 2011 at 13:32

1 Answer 1

5

I think you need to save the products before you save the category because you don't have a Cascade on the HasMany. And you need to change the add product methods to keep the relation

foreach (var product in products)
{
    category.AddProduct(product); 
    product.Category = category;
} 
Sign up to request clarification or add additional context in comments.

6 Comments

Product is a child of Category. Product cannot be created without category.
@Nagesh Why is that? you can save it while it's null, anyway you need to changed the relation like I commented and added to my answer.
@Nagesh By the way, I think you need to understand what does inverse and cascase do. stackoverflow.com/questions/4883900/… Is my question about it when I learned NH... GOOD LUCK!
Kindly provide me some links where I can download documentation regarding Hibernate.
Tutorials that a friend of mine published: codecovered.net/2011/04/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.