Why does NHibernate remove and then insert compound elements when selected?

Can someone explain this little riddle to me about how NHibernate handles building blocks.

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 of this type:

 <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 make a selection, for example:

 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 join option to get a blog with posts, but then removes all comments and then inserts comments! Why is he doing this? If I do not use a transaction, it will ONLY execute the selection, not DELETE and INSERT, as I expected. What am I missing? I am using NHibernate 2.0

+4
source share
2 answers

I think you need to override Equals () and GetHashCode () in the comment. NHibernate does not have an identifier to continue equality, so you must determine what makes the comment object equal to another comment.

May be wrong :)


Edit

From: http://www.nhforge.org/doc/nh/en/index.html#components-incollections (7.2)

Note. If you are defining an ISet of constituent elements, it is very important to implement Equals () and GetHashCode () correctly.

And an example implementation of Equals / GetHashCode

http://www.nhforge.org/doc/nh/en/index.html#persistent-classes-equalshashcode (4.3)

+5
source

My question will be, why do you commit only if you need to make a choice? I believe that the reason it deletes all comments is that when a transaction commit is called, the blog object and its associated comments are cached in the session that is used to create the transaction. When you call commit, you call all the objects in the session that are saved, which causes the data to return to the database. I do not understand why it removes comments, but this is the correct behavior for saving objects.

I also came across this today :

NHibernate deletes all my collection and recreation of table updates.

This usually happens when NHibernate cannot determine which items are changed in the collection. Common reasons:

  • completely replace the permanent collection with a new instance of the collection
  • passes NHibernate a manually created object and invokes an update on it.
  • Serialization / deserialization of a persistent collection also seems to cause this problem.
  • update using inverse = "false" - in this case, NHibernate cannot build SQL to update a single item in the collection.

Thus, to avoid the problem:

  • transfer the same collection instance that you received from NHibernate to it (optional in the same session),
  • try using a different collection instead of (or) or
  • try using the inverse = "true" attribute for.
-1
source

All Articles