These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: How to NOT cascade Evict only? Context: Performance of Flush
PostPosted: Thu Jun 14, 2007 3:15 am 
Beginner
Beginner

Joined: Wed Nov 29, 2006 10:32 am
Posts: 34
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:
    1. Use delete-orphan instead of all-delete-orphan (i.e., cascading only does the classical "cascaded delete", but no save/update-cascading); and do save()s manually all around the world.
    QUESTION: This feature is not documented in 1.0.x or 1.2 - but it is there in 1.0.x's as well as in 1.2's code. Is it officially useable?

    2. Write a new CascadeStyle which does cascading always except if the CascadingAction is ActionEvict; and write a persister which overloads
    Code:
    public virtual Cascades.CascadeStyle[ ] PropertyCascadeStyles

    and returns such CascadeStyle instead of "all-delete-orphan".
    I'm quite sure that this is not a designed extension point of NHibernate; would it work (I know: I have to try - but maybe someone knows it wont work anyway)? would it be in the spirit of NHibernate to do this?

    3. Help Flush to ignore unchanged objects much more efficiently: Is there some hook where this can be done (as soon as possible = after as little as possible has been done with the object)?

    (After five minutes in the bathroom ... ;-) ): There is of course solution ...

    ... 4. Redefine the dirty flag (or define a "DeepDirty" property) so that parents of dirty children also count as dirty; and do the Evict based on this flag. Advantages: No undocumented/risky NHibernate playing-arounds; code remains as it is now (and the additional runtime should be negligible - our 1:n cascaded associations usually have 1..10 children).

    But I should (and want to) still ask: Is this algorithm - using eviction for Flush() optimization - reasonable and dependable?



Thanks a lot (and sorry for the long text ...)
Harald M.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 15, 2007 5:43 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
I too would like to know how to optimize this. We also maintain our our own dirty flags in our entities (they get set when any mapped property is changed and cleared by IInterceptor.PostFlush) and within a few months we will start work on our next release where we will convert our data imports to use NHibernate. Performance during these imports will be a major issue ...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.