John
John

Reputation: 495

NHibernate returns wrong List of objects

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?

Upvotes: 2

Views: 493

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

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

Upvotes: 2

Related Questions