Hello -
First, I'm shocked to hear that mutable="false" actually does full dirty checking in flush! (does it also create the shadow copies of the objects??? - maybe it does not, and the dirty checker immediately returns!?!?).
We plan(ned) to add mutable=false to a few heavily used classes mapped to views for searches, which currently take a few seconds for the useless flush at the end ...
So this won't work, it seems ...
---
As to what we do in general, here is some input:
We use NHibernate in a large project; and we use it for large amounts of data. When we found out about the flush problem, we decided to track the dirty state of our objects ourselves.
In all large projects I have done, from the start I require code generation for all entity classes; and I write my own collection classes (standard .Net and Java collections are usually too dumb). Thus, adding dirty tracking was not too much work (a few days, including complete regeneration in a project of maybe 20 developers ...).
Using this support, we have our own commit wrapper, which iterates over all objects in a session and does
* set flush mode to "never" if no object has changed;
* evict unchanged objects (which in itself is not too cheap, because evict does cascading on cascading associations) if there are only some non-dirty objects.
(Ah - and for accessing the objects in the session, we use a single call via reflection, because the entityByKeys collection is private in the session ...).
NHibernate certainly cannot be used "out of the box" in larger and more complex projects (500..5000 entity classes, non-trivial mappings like time-dependent data, import scenarios with [only] a few millions object to import, etc.etc.), but by wrapping it in a framework which hides everything (we even hide HQL behind our own query language), it can be used quite nicely ...
Regards
Harald
|