-->
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: Why hibernate flush on readonly query ?
PostPosted: Fri Nov 21, 2008 4:43 pm 
Regular
Regular

Joined: Thu Aug 28, 2003 2:42 pm
Posts: 77
Location: The Netherlands
I am using the lastest stable hibernate version (3.3.1)

Anyway: I am using auto flush and during a tx I perform a query-read from the db to do dome validation before performing saveOrUpdate.

Hibernate will perform a flush just before the query is executed like stated in the hibernate book.
However, my query is marked as readOnly on the Query interface.

Why does hibernate not use this to determine that a flush isn't needed ??

Because I am using READ_COMMITED I see no reason why it should flush..

I considering setting FlushMode to Commit, but I read that I can get stale date sometimes. Can somebody give me a few examples when this occurs ? As can't realy think of some in my case...

- Ed


Top
 Profile  
 
 Post subject: Re: Why hibernate flush on readonly query ?
PostPosted: Fri Nov 21, 2008 6:28 pm 
Newbie

Joined: Mon Nov 03, 2008 4:07 am
Posts: 4
http://forum.springframework.org/archive/index.php/t-26034.html
I think this is by design. The above link might help you to eliminate the flushing on read-only queries. Let me know if you need to see the code.

Thanks,
Ram.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 22, 2008 8:06 am 
Regular
Regular

Joined: Thu Aug 28, 2003 2:42 pm
Posts: 77
Location: The Netherlands
Thanks ramvaswani.
I am aware what is written in the spring topic (btw: i am not using the spring hibernate template, but I do use Spring), but that doesn't realy answer my original questions:

- Why does Hibernate triggers a flush on a read-only query. I know the hibernate code and see the conditions, but why isn't the read-only one of those conditions to not flush? I don't want to allow dirty reads anyway as my isolation level is set to READ_COMMITED. Shouldn't Hibernate takes this in to account?

- I am looking for examples not to switch completely to FlushMode.COMMIT? In the book they see that you can encounter stale data, but I don't really understand how that happens with the above isolation level.

Let me explain this more clear through an example:
Suppose that I perform several member and member status save/updates during a transaction with level READ_COMMITED. They aren't flushed yet.
I then perform a read in a validator just before an other member update to check if the login name of the member already exists. With Auto flush, Hibernate will try to flush and then perform the read. This is conform the explanation in the hibernate book, for reasons of stale data. But I don't really understand when this could happen with the above isolation level. That is: until the transaction isn't commited, I will not be able to read the flushed members anyway (dirty reads aren't allowed in this level) so I am trying to understand when this Stale object situation, the one they warm you for in the book, could occur.
If not, which I think is the case, I can better just set the Flush Mode to Commit globally, not ??

(Now I change the flush mode to commit when I perform this read during a transaction to overcome the auto flush).

Any idea's are more then welcome?

-- Ed


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 22, 2008 2:17 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
In the book they see that you can encounter stale data, but I don't really understand how that happens with the above isolation level.


Until you flush your session there may be differences between the in-memory state and what is actually in the database. Since all queries (read-only or not) can only see what is in the database the result of the query may be different depending on if a flush has happened before the query or not. Consider this example.

You have a table of users. To begin with there are users Adam and Anton. Anton calls in to tell you that he has changed his name to Bert. So you load Anton and change the name to Bert. Now, without flushing the session you do a query to find all users that has a name starting with the letter 'A'. This query will find Adam and Bert. If you flush the session first, this query only finds Adam.

Quote:
But I don't really understand when this could happen with the above isolation level. That is: until the transaction isn't commited, I will not be able to read the flushed members anyway...


Yes you will be able to do this since they are part of your current transaction. The READ_COMMITTED isolation level means that your transaction can't see changes made by OTHER transaction until the other transaction has been committed. Changes made by your own transaction are visible.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 22, 2008 2:28 pm 
Regular
Regular

Joined: Thu Aug 28, 2003 2:42 pm
Posts: 77
Location: The Netherlands
He Nordborg, Thanks for the details on the isolation level, that certainly clears up some things.

nordborg wrote:
Now, without flushing the session you do a query to find all users that has a name starting with the letter 'A'. This query will find Adam and Bert. If you flush the session first, this query only finds Adam.


I don't understand this. I would see it wll return the objects Adam and Anton before it's flushed as we read exactly from the db. Why would it already returned the modified object with the name Bert?, as it's only located in the session and we didn't flush yet.

-- Ed


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 22, 2008 6:02 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
Why would it already returned the modified object with the name Bert?, as it's only located in the session and we didn't flush yet.


It's is true that in the db the query will find Adam and Anton, but in the Hibernate session Anton has been renamed to Bert. Since a single Hibernate session only can contain one object representing the Anton row it will return the very same instance that has already has it's name changed to Bert.

Just to make things clear, this only happens when everything happens in a single Hibernate session without flushing anything to the database or evict()-ing anything from the session. The default (AUTO) flush mode in Hibernate will flush the changes to the database before the query is executed and then the query would only find Adam.

Quote:
Can somebody give me a few examples when this occurs ? As can't realy think of some in my case...


Well, the example with Anton and Bert was maybe not a very good example, but in real world I guess things like this could happen when you least expect it.


Regarding the transaction isolation level there is also a REPEATABLE_READ isolation level (at least in some databases). With this level, a given query will always return the same result if it is repeated in the same transaction, even if things have been updated by the same or other committed transactions. So, I guess with this isolation level it would make sense to not flush the session, since it will not affect the result of the query. If you are going for this transaction isolation level you might just as well go for the FlushMode.COMMIT as well.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 23, 2008 7:49 am 
Regular
Regular

Joined: Thu Aug 28, 2003 2:42 pm
Posts: 77
Location: The Netherlands
Thanks for the explanation.


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.