-->
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: Query regarding FlushMode
PostPosted: Thu Jul 22, 2004 6:43 am 
Beginner
Beginner

Joined: Tue Jul 20, 2004 1:53 am
Posts: 43
Location: India
Hi,

I am using Hibernate 2.1 with ORACLE 8. I read about FlushMode in "Hibernate In Action" book (from Manning EAP), and thought I understood it. But when I tried out a code sample, it was not working the way I was expecting it to, and it'd be great if someone here can help me out.

My code is as :
Code:
    public void testIfChangesAreReflectedInTheSameTransaction()
        throws HibernateException
    {
        final long id = 110000000037773404L;
        Session session1 = getSessionFactory().openSession(); // open a session
        session1.setFlushMode(FlushMode.AUTO);                // force changes to be reflected in the same session
        Transaction t1 = session1.beginTransaction();         // being transaction
        Loan l1 = (Loan) session1.load(Loan.class, new Long(id));
        String oldValue = l1.getFicoOverrideBy();
        String newValue = Long.toString(System.currentTimeMillis());
        l1.setFicoOverrideBy(newValue);                      // making a change in the session
        System.out.println("[1] Changed Value to " + newValue + " from " + oldValue);
        Loan l2 = (Loan) session1.createQuery("from Loan l where l.id=" + id)
            .uniqueResult();                                 // running another query to load the same entity
        System.out.println("[1] Value read from DB is " + l2.getFicoOverrideBy()); // are changes flushed to DB? Yes
        t1.commit();                                         // commit transaction
        session1.close();                                    // close session

        Session session2 = getSessionFactory().openSession(); // open another session
        session2.setFlushMode(FlushMode.COMMIT);              // force changes NOT to be reflected in the same session
        Transaction t2 = session2.beginTransaction();         // being transaction
        Loan l3 = (Loan) session2.load(Loan.class, new Long(id));
        oldValue = l3.getFicoOverrideBy();
        newValue = Long.toString(System.currentTimeMillis());
        l3.setFicoOverrideBy(newValue);                       // making a change in the session
        System.out.println("[2] Changed Value to " + newValue + " from " + oldValue);
        Loan l4 = (Loan) session2.createQuery("from Loan l where l.id=" + id)
            .uniqueResult();                                  // running another query to load the same entity
        System.out.println("[2] Value read from DB is " + l4.getFicoOverrideBy()); // are changes flushed to DB? Yes
        t2.commit();                                          // commit transaction

        session2.close();                                     // close session
    }


In the first Session, I want (uncomitted) changes made in a transaction to be visible to queries made within that same transaction. In the second Session, I want (uncomitted) changes made in a transaction not to be visible to queries made within that same transaction.

The SQL statements fired are :
Code:
Hibernate: select loan0_.LOAN_ID as LOAN_ID0_, [..] loan0_.WEBSITE_ID as WEBSITE_ID0_ from LOAN loan0_ where loan0_.LOAN_ID=?
Hibernate: update LOAN set VERSION_NUMBER=?,  [..] WEBSITE_ID=? where LOAN_ID=? and VERSION_NUMBER=?
Hibernate: select loan0_.LOAN_ID as LOAN_ID, [..] loan0_.WEBSITE_ID as WEBSITE_ID from LOAN loan0_ where (loan0_.LOAN_ID=110000000037773404 )
Hibernate: select loan0_.LOAN_ID as LOAN_ID0_, [..] loan0_.WEBSITE_ID as WEBSITE_ID0_ from LOAN loan0_ where loan0_.LOAN_ID=?
Hibernate: select loan0_.LOAN_ID as LOAN_ID, [..] loan0_.WEBSITE_ID as WEBSITE_ID from LOAN loan0_ where (loan0_.LOAN_ID=110000000037773404 )
Hibernate: update LOAN set VERSION_NUMBER=?, PRIMARY_BORROWER_ID=?,[..] WEBSITE_ID=? where LOAN_ID=? and VERSION_NUMBER=?


The order of the SQL statement suggests that I'd get what I want to. But the output of the program is :
Code:
[1] Changed Value to 1090492584966 from 1090492565201
[1] Value read from DB is 1090492584966
[2] Changed Value to 1090492585076 from 1090492584966
[2] Value read from DB is 1090492585076


The first Session works fine - changes made in a transaction are visible to queries fired from that transaction. But the second Session is not working for me, where I would want changes made in a transaction not to be visible to queries fired in that transaction. Please advise me how to accomplish this effect.

Thanks,
Binil


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 6:48 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Quote:
System.out.println("[2] Value read from DB is " + l4.getFicoOverrideBy()); // are changes flushed to DB? Yes


no, in fact the query is retrieving the id of the object, and then the session knows it handle that object. As you have updated it before... that doesn't mean the sql has been executed.

Try to comment the second commit, and you'll see no seond update will appear

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 6:51 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
furthermore,
Quote:
Hibernate: select loan0_.LOAN_ID as LOAN_ID0_, [..] loan0_.WEBSITE_ID as WEBSITE_ID0_ from LOAN loan0_ where loan0_.LOAN_ID=?
Hibernate: update LOAN set VERSION_NUMBER=?, [..] WEBSITE_ID=? where LOAN_ID=? and VERSION_NUMBER=?
Hibernate: select loan0_.LOAN_ID as LOAN_ID, [..] loan0_.WEBSITE_ID as WEBSITE_ID from LOAN loan0_ where (loan0_.LOAN_ID=110000000037773404 )
Hibernate: select loan0_.LOAN_ID as LOAN_ID0_, [..] loan0_.WEBSITE_ID as WEBSITE_ID0_ from LOAN loan0_ where loan0_.LOAN_ID=?
Hibernate: select loan0_.LOAN_ID as LOAN_ID, [..] loan0_.WEBSITE_ID as WEBSITE_ID from LOAN loan0_ where (loan0_.LOAN_ID=110000000037773404 )
Hibernate: update LOAN set VERSION_NUMBER=?, PRIMARY_BORROWER_ID=?,[..] WEBSITE_ID=? where LOAN_ID=? and VERSION_NUMBER=?


show that the update is really done at the end.

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 7:02 am 
Beginner
Beginner

Joined: Tue Jul 20, 2004 1:53 am
Posts: 43
Location: India
Hi Anothony,

Thanks for replying.

anthony wrote:
no, in fact the query is retrieving the id of the object, and then the session knows it handle that object. As you have updated it before... that doesn't mean the sql has been executed.


I agree that the order in which SQL is fired is different in the two cases - select-update-select in the first case and select-select-update in the second case.

Since my HQL restriction is based on the id, Hibernate might be able to use its first-level cache and save a trip to the DB. On thinking a bit more on the usecase, I think it should not go to the DB again for selections restricted by ids.

I have hibernate.show_sql to true. So why is Hibernate going to the DB again, instead of using the cache? Please help me understand this.

Meanwhile I will try modifying the test to use a restriction based on some non-unique field.

Thanks,
Binil


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 7:21 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
use session.get

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 8:38 am 
Beginner
Beginner

Joined: Tue Jul 20, 2004 1:53 am
Posts: 43
Location: India
binil wrote:
Meanwhile I will try modifying the test to use a restriction based on some non-unique field.


That worked!

But I have some doubts about the behaviour of the earlier test i.e. when the HQL restriction was based on a unique-field. Hibernate was firing a SQL query - yet once it got the result from the DB it threw away the result in favour of the copy of the entity in the first-level cache. Why is this happening? Is there any way to force Hibernate never to go to the DB for queries that are based on unique-fields, if the entity is already cached in the session?

Please let me know.

_________________
Thanks,
Binil Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 8:39 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
what about using session.get ???

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


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.