Reputation: 838
Scenario
I have a category class in DB:
CREATE TABLE [dbo].[Category](
[pk_cat_id] [int] NOT NULL,
[name] [varchar](50) NOT NULL,
[parent_cat_id] [int] NULL
CONSTRAINT [PK_Category] PRIMARY KEY NONCLUSTERED
(
[pk_cat_id] ASC
))
Category class has association to itself. It is a recursive, bidirectional association(many-to-one and one-to-many).
Both refer to the same foreign key column: parent_cat_id.
A category can have one parent at-most and no or more child categories.
This is Category.hbm.xml:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2"
assembly ="NHibernateIntro.Core"
namespace ="NHibernateIntro.Core.Domain">
<class name="Category" table="Category">
<id name="CategoryId" column="pk_cat_id">
<generator class="hilo"/>
</id>
<property name="Name" column="name" type="string" length="50" not-null="true" />
<many-to-one name="ParentCategory" class="Category" column="parent_cat_id" />
<bag name="childCategories" cascade="all-delete-orphan" inverse="true">
<key column="parent_cat_id"/>
<one-to-many class="Category"/>
</bag>
</class>
</hibernate-mapping>
This is Category.cs:
using System;
using System.Collections.Generic;
using Iesi.Collections.Generic;
namespace NHibernateIntro.Core.Domain
{
public class Category
{
private Category parent_category;
private ISet<Category> child_Categories = new HashedSet<Category>();
public virtual int CategoryId { get; set; }
public virtual string Name { get; set; }
public Category() { }
public Category( string cat_name )
{
Name = cat_name;
}
public virtual Category ParentCategory
{
get
{
if (parent_category == null)
parent_category = new Category();
return parent_category;
}
set{ parent_category = value; }
}
public virtual ISet<Category> childCategories
{
get { return child_Categories; }
set { child_Categories = value; }
}
}
}
This is the Main method:
public static void Run(ISessionFactory factory)
{
int computerId = 1;
using (ISession session = factory.OpenSession())
using (session.BeginTransaction())
{
Category computer = session.Get<Category>(computerId); // **This line causes Error(stated below)**
// Please see 'CONFUSING' tag below.
Category laptops = new Category("Laptops");
computer.childCategories.Add(laptops);
laptops.ParentCategory = computer;
session.Save(laptops);
session.Transaction.Commit();
}
}
CONFUSING : When i debugged the code it stuck here at this line: "set{ parent_category = value; }". I am confused because I am assigning to Cateory then why setter of parentCategory is being called here?
Error: Invalid Cast (check your mapping for property type mismatches); setter of NHibernateIntro.Core.Domain.Category
Inner Error: Unable to cast object of type'NHibernate.Collection.Generic.PersistentGenericBag1[NHibernateIntro.Core.Domain.Category]'
to type 'Iesi.Collections.Generic.ISet
1[NHibernateIntro.Core.Domain.Category]'.
kINDLY hELP!!
Upvotes: 2
Views: 6801
Reputation: 49301
Change
private ISet<Category> child_Categories = new HashedSet<Category>();
to
private ICollection<Category> child_Categories = new HashSet<Category>();
and it should work. Note that I'm using the C# HashSet, not the Iesi.Collections HashedSet. More recent versions of NHibernate may support HashSet directly.
Upvotes: 5
Reputation: 838
Use set in the mapping file instead of bag. Because ISet cannot be casted to IList and bag mapping is compatible with a .NET IList
Upvotes: 5