Why does NHibernate delete then insert composite-elements on select?
nhibernate
Solution
I think you need to override Equals() and GetHashCode() on Comment. NHibernate doesn't have an ID to go on for entity equality so you have to define what makes a comment entity equal to another comment.
Could be wrong :)
Edit
From nhibernate.info (8.2)
Note: if you define an ISet of composite elements, it is very important to implement Equals() and GetHashCode() correctly.
And an example of implementing Equals / GetHashCode from nhibernate.info (4.3)
public class Cat
{
...
public override bool Equals(object other)
{
if (this == other) return true;
Cat cat = other as Cat;
if (cat == null) return false; // null or not a cat
if (Name != cat.Name) return false;
if (!Birthday.Equals(cat.Birthday)) return false;
return true;
}
public override int GetHashCode()
{
unchecked
{
int result;
result = Name.GetHashCode();
result = 29 * result + Birthday.GetHashCode();
return result;
}
}
}
Problem
Can someone explain this little mystery to me about how NHibernate handles composite elements. I have classes that look like this; ``` public class Blog { public virtual int Id { get; private set; } public virtual ISet<Comment> Comments { get; set; } } public class Comment { public virtual string CommentText { get; set; } public virtual DateTime Date { get; set; } } ``` and mappings like this; ``` <class name="Blog" table="blog"> <id name="Id" column="id" unsaved-value="0"> <generator class="hilo"/> </id> <set name="Comments" table="blog_comments"> <key column="blog_id" /> <composite-element class="Comment"> <property name="CommentText" column="comment" not-null="true" /> <property name="Date" column="date" not-null="true" /> </composite-element> </set> </class> ``` However when i perform a select like this; ``` using (ITransaction transaction = session.BeginTransaction()) { Blog blog = session.CreateCriteria(typeof(Blog)) .SetFetchMode("Comments", FetchMode.Eager) .Add(Expression.IdEq(2345)) .UniqueResult(); transaction.Commit(); } ``` NHibernate issues a select with a join to get the blog with posts BUT then deletes all comments and then inserts the comments! Why is it doing this? If i do not use a transaction then it will ONLY perform the select and not the DELETE and INSERT as I would expect. What am I missing? I am using NHibernate 2.0