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.  [ 7 posts ] 
Author Message
 Post subject: Flush Performance for Read Only Entities
PostPosted: Tue Feb 20, 2007 12:11 pm 
Newbie

Joined: Tue Feb 20, 2007 12:01 pm
Posts: 6
Hi All,

I have many objects mapped using nhibernate. These objects are read only - they do not change.

I am caching both the objects themselves using SysCache, as well as the queries that are getting these objects.

When a query calls IList NHibernate.Impl.SessionImpl.Find(CriteriaImpl), one of the last calls is to Boolean NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet). This call is taking a lot of resources, and I am wondering why it's necessary. Can I tell NHibernate that the object is read only and please don't check for changes in the Flush? I am suprized that I have not found a way to tell NHibernate that an object is always read only.

I am concerned about using Evict - will using Evict affect the presence of the object in my 2nd level cache? I want to remove the object from the list of objects to persist, but not from the cache.

Thanks,

JP


Top
 Profile  
 
 Post subject: Dynamic Updates
PostPosted: Tue Feb 20, 2007 6:33 pm 
Beginner
Beginner

Joined: Wed Nov 29, 2006 5:33 pm
Posts: 28
Location: Chicago, IL
I don't know if this will help any. Really just a shot in the dark. I do know that the NHibernate manual lists dynamic-update as one of the attributes of the class / subclass / joined-subclass mapping elements.

My understanding is that when this attribute is set to true, NHibernate checks which properties of your object are dirty (don't ask me how) before saving the object and only sends the properties that have changed down the wire. What the manual does not say is whether or not, if no properties have changed, does NHibernate bother sending anything. My guess it that NHibernate is smart enough to do this as I have a good deal of faith in the implementors, but I can't say that I have any experience with this feature yet.

Hope that helps you out a bit.

_________________
Chuck

Not in the face! Not in the face!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 20, 2007 10:50 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
I can see two problems here. One is how to tell NHibernate an object is readonly. Second is to avoid unnecessary flush.

From NH Documentation (http://www.hibernate.org/hib_docs/nhibernate/html/mapping.html#mapping-declaration-class), I find this:
Quote:
Immutable classes, mutable="false", may not be updated or deleted by the application. This allows NHibernate to make some minor performance optimizations.


For the second problem you would change the FlushMode like this
Code:
session.FlushMode = FlushMode.Commit

http://www.hibernate.org/hib_docs/nhibernate/html/manipulatingdata.html#manipulatingdata-flushing

Hope this helps


Top
 Profile  
 
 Post subject: Nhibernate shouldn't do dirty check on mutable=false
PostPosted: Wed Feb 21, 2007 11:18 am 
Newbie

Joined: Tue Feb 20, 2007 12:01 pm
Posts: 6
Thanks for the suggestions.

Yes, I found the mutable=false and the FlushMode=Commit yesterday and tried them.

I found that NHibernate still does a dirty check on even mutable=false objects. Apparently Nhibernate determines if the object has been changed, and if so throws an exception. While this is good for finding cases where someone changes an object that is read-only, the performance hit is huge. I have 500 objects that are read only and NHibernate insists on iterating thru every one of them checking if they are dirty.

Also, I really WANT NHibernate to flush before query, I just dont want it to try to flush my mutable=false objects - that's just not necessary and costly.

I am leaning towards changing NHibernate so it doesn't do a dirty check on mutable=false entities - these objects should be skipped when doing a flush.

JP


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 21, 2007 3:46 pm 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
This sounds like it will be a problem for me as well. Im starting a project where we were planning on caching all of the products in our catalog which could be 3000+. This will be a hug hit for me if just want to update a users account info for example.

Im really surprised that immutable objects are checked for changes. I would rather have it ignore immutable objects as opposed to throwing an exception if the object has changed. My object model should prevent changes so why should Nhibernate take on that responsibility as well.

SecretSquirrel, I'm not sure what is involved in changing NHibernate to support this but Id be interested in seeing what you come up with.

A good strategy might be to store immutable data in a different location within the cache.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 21, 2007 11:45 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
I could come up with 2 solutions to the scenario but I am not sure if they are the best/official solutions.


Open 2 sessions. 1 for read-write objects and 1 for read only objects. But session management may pollute your code.

or

Evict() all read only objects from session right after you Get()/Load() them. By applying second level cache, no extra database access is required.

Hopes this helps


Top
 Profile  
 
 Post subject: Flush and mutable=false etc. - what we do
PostPosted: Thu Apr 05, 2007 6:06 am 
Beginner
Beginner

Joined: Wed Nov 29, 2006 10:32 am
Posts: 34
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


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.