Hi -
we use NHibernate (currently still 1.0.x) in a large production software; and even use it for large imports of data, because these imports use standard business functionality which we do not want to duplicate e.g. in SQL stored procedures or other programs.
The imports run to some millions of objects; a session is committed and closed every 1000 or so new or modified objects. This works fine in principle.
However, we found that a session with around 1000 objects to be written also contains around 2000..3000 objects which have not changed (referenced objects which already were in the database).
And with 1.0.2, we measured that the biggest bottleneck is the dirty check deep inside Flush(); and there, it is the retrieval of all property values before anything else is done which takes (took?) so long (therefore, IInterceptor's FindDirty method is already "too late in the game" to improve Flush()'s performance).
So we do a dirty trick: Before the Flush, we evict all objects which have not changed - we have our own dirty flag anyway in all objects, so this is easy.
Confession: I'm not sure that we measured this with all combinations of reflection vs. reflection optimized property accesses - I'll do this ASAP. Still, accessing a single flag in an object of ours to skip an object is always much faster than accessing all properties in an object in any generic way ...
Now the problem is: Because we also use cascading (with parent-child-associations - we write "all-delete-orphan"), the above is unfortunately
wrong - if a child is changed, but not its parent, the parent will be evicted and (due to the cascading) will also evict its child :-(
Possible solutions which come to (my) mind:
Thanks a lot (and sorry for the long text ...)
Harald M.