-->
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.  [ 10 posts ] 
Author Message
 Post subject: Query with where clause on unflushed property values
PostPosted: Wed Apr 26, 2006 7:50 am 
Newbie

Joined: Wed Apr 26, 2006 5:21 am
Posts: 14
HI!

We are evaluating Hibernate (3.2.0CR1) for a large ERP app, that uses our own OR mapper at the moment.

One of the biggest advantages of Hibernate over own OR mapper would be the automatic flush on commit, resulting in minimal lock time (updated, but not yet committed rows).

So, I set FlushMode.COMMIT. Also, using EH 2nd level cache.

Now, if I change a property, save and then do a query without that property in the where clause, it finds the object and I get the up-to-date object with the changed property. This is good.

But when I use the changed property in the where clause, it will not find the object, because the
a) the change is not yet reflected in the database
b) Hibernate Query only runs on the DB, not on the cache

I have read relevant docs, went through the tutorial and searched in the forum. So, I learned, that this is not a bug, but a well-documented behavior.

My question is: Why?

Why does Hibernate not search in the DB *and* the cache and returns results from both?

Is this a planned feature?

Thanks!

Thomas

Code:
-------
Code:
      Session session = HibernateUtil.getSessionFactory().getCurrentSession();
      session.beginTransaction();
      session.setFlushMode(FlushMode.COMMIT);

      Person aPerson = (Person) session.load(Person.class, personId);
      aPerson.setAge(20);
      session.save(aPerson);
     
      List persons = session.createQuery("from Person where age = 20").list();
      for (int i = 0; i < persons.size(); i++) {
        Person thePerson = (Person) persons.get(i);
        System.out.println("Person: " + thePerson.getFirstname() +
                " " + thePerson.getLastname() + ", " + thePerson.getAge());
      }
     
      session.getTransaction().commit();



Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 8:30 am 
Senior
Senior

Joined: Mon Aug 22, 2005 5:45 am
Posts: 146
I strongly recommend to get familiar with the hibernate concept of SessionFactory and Session.
a given session has ALWAYS synchronized state.

example (abstract):
Person p = session.load(Person.class, 1)
p.setName("newname")
session.save(p)

(p is not yet flushed to DB)
now if you query persons after name "newname" you WILL get person with ID=1, as long as you operate on the same session instance.

If you don't, then this might be due to 2nd level cache configuration, which is out of (direct) hibernate control.

_________________
Please don't forget to give credit, if my posting helped to solve your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 8:49 am 
Newbie

Joined: Wed Apr 26, 2006 5:21 am
Posts: 14
HI!

Even if I disable the 2nd level cache, it still does not find my changed person with age = 20.

It does find it, if I set FlushMode.AUTO.

Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 9:29 am 
Senior
Senior

Joined: Mon Aug 22, 2005 5:45 am
Posts: 146
tboerkel wrote:
HI!

Even if I disable the 2nd level cache, it still does not find my changed person with age = 20.

It does find it, if I set FlushMode.AUTO.

Thomas


you you checked that you operate on the same session instance?

_________________
Please don't forget to give credit, if my posting helped to solve your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 9:38 am 
Newbie

Joined: Wed Apr 26, 2006 5:21 am
Posts: 14
HI!

Yes, please look at the code I provided.

Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 9:54 am 
Senior
Senior

Joined: Mon Aug 22, 2005 5:45 am
Posts: 146
checking out this FlushMode.COMMIT I found out this is a special case.
as you can read from
http://www.hibernate.org/hib_docs/v3/re ... e-flushing
the concept is different here.
The idea of FlushMode.COMMIT is that the session will not be synchronized unless you call session.commit()
also, any queries released do not consider unflushed operations.
So if you need synchronized state you should use FlashMode.AUTO

_________________
Please don't forget to give credit, if my posting helped to solve your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 10:17 am 
Newbie

Joined: Wed Apr 26, 2006 5:21 am
Posts: 14
HI!

Yes, I know. That was my original question.

We would like to flush only on Commit.

Why does Hibernate need to flush the session data, in order to be able to use the latest data in the query. Why does it not execute the query also on the cache?

Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 27, 2006 5:26 am 
Senior
Senior

Joined: Mon Aug 22, 2005 5:45 am
Posts: 146
tboerkel wrote:
HI!

Yes, I know. That was my original question.

We would like to flush only on Commit.

Why does Hibernate need to flush the session data, in order to be able to use the latest data in the query. Why does it not execute the query also on the cache?

Thomas


remember the concept of data-commitment.
if you use FlushMode.COMMIT what you want is to commit your changes explicitly. Before you do so, the idea is that your data changes are only valid for your session. They are not persistent on DB level.
It would be wrong if hibernate queries the session cache as long as the data has not yet been comitted.
When you got the idea, you understand hibernate work just correctly.

_________________
Please don't forget to give credit, if my posting helped to solve your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 27, 2006 6:01 am 
Newbie

Joined: Wed Apr 26, 2006 5:21 am
Posts: 14
HI!

Data that is not committed, is valid in the current session, that's right.

This data can be found by a where clause, if a flush is being done (either automatically oder explicit) after save and before commit.
This is consistent with plain JDBC programming. Data, that I have updated/flushed into the DB, can be read back by me and only by me (until commit).

But Hibernate already uses unflushed session data, if it can find the object through the query. Then Hibernate delivers the object, that is already in the Session cache with the unflushed changes.
But the query can only find the object, if there are no changed (and unflushed) properties used in the where clause. And this is inconsistent IMHO.
On one hand, Hibernate delivers unflushed data, on the other hand, it cannot find the object, if the where clause references unflushed data.

Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 28, 2006 7:00 am 
Newbie

Joined: Wed Apr 26, 2006 5:21 am
Posts: 14
HI!

Can any of the Hibernate developers please comment on this?

Thanks!

Thomas


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