2

I don't understand why NHibernate returns a wrong list of children objects. I have the database with two tables: Category and Product. Product has a foreign key, the Id of Category.

    Category table                          Product table
Id | Name | Description           Id | Name | Description | Category_Id

Mappings:

    <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NHDemo"
                   namespace="NHDemo">
  <class name="Category">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="Name" />
    <property name="Description" />
    <set name="Products" inverse="true" lazy="true" >
      <key column="Id"/>
      <one-to-many class="Product"/>
    </set>
  </class>
</hibernate-mapping>

And:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NHDemo"
                   namespace="NHDemo">
  <class name="Product">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="Name"/>
    <property name="Description"/>
    <many-to-one name="Category" class="Category" fetch="select">
      <column name="Category_Id" not-null="true" />
    </many-to-one>
  </class>
</hibernate-mapping>

C# code:

namespace NHDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var cfg = new Configuration();
            cfg.Configure();
            var sessionFactory = cfg.BuildSessionFactory();
            using(var session = sessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var results = session.CreateCriteria<Category>().List<Category>();
                foreach (var category in results)
                {
                    Console.WriteLine(category.Name);
                    foreach (var product in category.Products)
                        Console.WriteLine(product.Name);
                }
            }
        }
    }

    public class Product
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
        public virtual Category Category { get; set; }
    }

    public class Category
    {
        private ISet<Product> products;
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
        public virtual ISet<Product> Products
        {
            get { return products; }
            set { products = value; }
        }
    }
}

Meaning that i have two categories and four products, as they are linked, i'm expecting the results:

Category1
 Product1
 Product2
Category2
 Product3
 Product4

But i'm getting the result:

Category1
 Product1
Category2
 Product2

What am i doing wrong?

1 Answer 1

2

The answer is here: The collection key must be mapped to the column containing the reference to the parent.

Adjusted collection mapping (see the <key> column attribute value)

<set name="Products" inverse="true" lazy="true" >
  <key column="Category_Id"/>                 <--- here is the change
  <one-to-many class="Product"/>
</set>

So the Category_Id is the place, where NHibernte must search for a reference

Sign up to request clarification or add additional context in comments.

Comments

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.