-->
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.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Commit for a SELECT in HelloWorld? IMHO not a good move!
PostPosted: Fri Jan 18, 2008 12:37 pm 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
It always bugged my mind to think why Hibernate uses a transaction for a SELECT. It even does that in the Hello World application.

Maybe this has to do with the database isolation levels, but it does not make sense to me to encorage this as the default.

By default, READ operations in a DB should not require a transaction.

Or maybe I am missing something! Can someone help?

Code:
private List listEvents() {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    List result = session.createQuery("from Event").list();
    session.getTransaction().commit();
    return result;
}


Commiting a select looks odd to me, but i may be missing something deeper here.


Last edited by saoj on Mon Jan 21, 2008 6:56 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 18, 2008 10:22 pm 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
Anyone? This is a mystery! A commit for a select looks really ugly to me. Am I missing something?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 19, 2008 3:20 pm 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
I guess I have to assume that Hibernate has a good reason to commit a select. I will keep using iBatis, pBeans or something else.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 20, 2008 9:40 am 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
Actually, after checking other ORM solutions, I think Hibernate is over-complicating something very simple. A commit to a select should not be the default behavior for Hibernate.

Hopefully version 4.0 will fix that. Until there, I will keep using other simpler stuff like MentaBeans (http://recipes.mentaframework.org/posts/list/21.page), pBeans and iBatis.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 2:31 am 
Newbie

Joined: Mon Jun 11, 2007 1:34 pm
Posts: 11
I use Hibernate 3.2.5 and i don't have to put session.beginTransaction(); and session.getTransaction().commit(); to make a select, are you sure you are doing things the right way?

EDIT:
I got curious and look-up this:
http://www.hibernate.org/hib_docs/v3/reference/en/html/transactions.html#transactions-demarcation

It's funny becouse i never use beginTransaction() and commit() to make a read-only operation and results were ok. I guess i'll put some beginTransactions and commits just in case.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 8:19 am 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
The first hibernate application according to the official documentation that you can read here:

http://www.hibernate.org/hib_docs/v3/re ... l-firstapp

Code:
private List listEvents() {

    Session session = HibernateUtil.getSessionFactory().getCurrentSession();

    session.beginTransaction();

    List result = session.createQuery("from Event").list();

    session.getTransaction().commit();

    return result;
}


What was your conclusion from what you read? I don't digg hibernate for encouraging the use of a transaction around a READ operation. I may be wrong, but I need someone to tell me why I am wrong, but this makes no-sense to me!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 11:32 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
http://www.hibernate.org/42.html

http://www.hibernate.org/403.html

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 2:39 pm 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
From here: http://www.hibernate.org/403.html

I have concluded that you DO NOT need to demarcate a transaction around a READ operation (or many consecutive read operations). Hibernate suggests that you do this just to make things more complicated than they should. OF COURSE, if you are doing an WRITE (insert/update/delete) then you need a transaction, but my post is about a READ (select) and about the HelloWorld hibernate code that uses a transaction around a simple select operation.

If Hibernate is so worried about this, it should rollback or commit any open transaction on a session close. Why complicate a simple stuff?

Look here: (this is what the above link states)

Look at the following code, which accesses the database without transaction boundaries:

Code:
Session session = sessionFactory.openSession();
session.get(Item.class, 123l);
session.close();


By default, in a Java SE environment with a JDBC configuration, this is what happens if you execute this snippet:

1. A new Session is opened. It doesn’t obtain a database connection at this point.

2. The call to get() triggers an SQL SELECT. The Session now obtains a JDBC Connection from the connection pool. Hibernate, by default, immediately turns off the autocommit mode on this connection with setAutoCommit(false). This effectively starts a JDBC transaction!

3. The SELECT is executed inside this JDBC transaction. The Session is closed, and the connection is returned to the pool and released by Hibernate — Hibernate calls close() on the JDBC Connection. What happens to the uncommitted transaction?

The answer to that question is, “It depends!” The JDBC specification doesn’t say anything about pending transactions when close() is called on a connection. What happens depends on how the vendors implement the specification. With Oracle JDBC drivers, for example, the call to close() commits the transaction! Most other JDBC vendors take the sane route and roll back any pending transaction when the JDBC Connection object is closed and the resource is returned to the pool.

Obviously, this won’t be a problem for the SELECT you’ve executed!

Yes! The above sentence in red was said by Hibernate Documentation, not me. So I am concluding I am correct when I say that explicit using a transaction for a read operation is a waste of simplicity.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 3:04 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
There is no such thing as "no transaction for a select". You still don't understand how autocommit works.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 3:18 pm 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
christian wrote:
There is no such thing as "no transaction for a select". You still don't understand how autocommit works.


I understand that a transaction is always there, even when auto_commit is ON and even when you do a SELECT

BUT

As you said in the documentation, there is no need to worry about this when you are doing a select, in other words, there is no need to explicit demarcate you select with a transaction.

When you close the session, the transaction will be rolledback or committed and it does not matter for the SELECT anyways.

Hibernate should be smart enough to detect a non-commited or non-rolledback transaction when you close your session and rollback (or commit you choose) the transaction. Having to to worry about demarcating my READs with transactions is not the end of the world, is not wrong, but is a lack of simplicity from Hibernate. This is my personal opinion!

Don't you agree?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 3:55 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Auto-commit is a) less safe b) hurting performance c) reducing scalability and d) complicating application design/maintenance. Of course it should be disabled by default and Hello World readers should be introduced to proper ACID transaction demarcation as soon as possible.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 4:14 pm 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
christian wrote:
Auto-commit is a) less safe b) hurting performance c) reducing scalability and d) complicating application design/maintenance. Of course it should be disabled by default and Hello World readers should be introduced to proper ACID transaction demarcation as soon as possible.


Maybe like Einstein said we can both measure different results and both be right. It will depend on our relative velocity.

Anyways, I am not talking about auto-commit. I am talking about have to demarcate a read operation or a set o read operation. Using auto-commit on a bunch of read operations is probably BAD as many commits will be done unnecessary. I agree with that. But having to demarcate my set of reads with a hibernate transaction when auto-commit is OFF by default is not cool.

a)

There is no risk at all. Unless you are using a non-sense JDBC driver with a non-sense, non-default, database isolation level.

b)

I don't think so. This is what you think, but you cannot be right about that the same way I cannot be right that it will not hurt performance. It will depend on many things and on the scenario. I would think that under the default scenario it will not hurt performance at all.

c)

same as b

d)

??? I don't think so, but that's my opinion.

Maybe the problem is:

99% of people that use JDBC do not commit on a select. That's common-sense because there is nothing to be committed.

COMMIT = Make sure my change is persisted and safe in the disk or wherever. Any DB will tell you this about commit.

Now if Hibernate want to push everybody to demarcate transactions around read operations it surely can. It is not the end of the world. It is just against the KISS principle, in my humble opinion.

I will keep not demarcating a simple select with a transaction. I hope Hibernate session is smart enough to close its underlaying transaction. I will let it choose if it wants to commit or rollback my select. (duh!)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 23, 2008 10:08 am 
Newbie

Joined: Wed Jan 23, 2008 10:02 am
Posts: 3
I noticed that if I execute a select operation within a transaction an unwanted operation occurs... It's a bit upsetting.
Am I missing something?

simone


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 27, 2008 11:33 am 
Newbie

Joined: Fri Jan 18, 2008 12:33 pm
Posts: 9
siras wrote:
I noticed that if I execute a select operation within a transaction an unwanted operation occurs... It's a bit upsetting.
Am I missing something?

simone


What do you mean? Can you explain better what kind of extra operation is happening?


Top
 Profile  
 
 Post subject: Re: Commit for a SELECT in HelloWorld? IMHO not a good move!
PostPosted: Wed Apr 13, 2011 5:15 pm 
Newbie

Joined: Wed Apr 13, 2011 5:03 pm
Posts: 1
The problem I am having with using a transaction with a select is the following:

Code:
    try {
      session = sessionFactory.getCurrentSession();
      transaction = session.beginTransaction();
      query = session.getNamedQuery("getTestByName", "t1");
      ret = query.list();
      success = true;
    } finally {
      if (transaction != null) {
        if (success) {
          transaction.commit();
        } else {
          transaction.rollback();
        }
      }
    }


That "commit" line throws an SQL exception because, even though that query named "getTestByName" is a select, hibernate is executing the following SQL statement:

Code:
update param set testId=null, stateId=null where testId=142346


Where obviously testId and stateId are a composite primary key, defined in the hibernate mapping as:

Code:
    <composite-id>
      <key-property name="testId" access="field">
        <column name="testId" sql-type="int" not-null="true"/>
      </key-property>

      <key-property name="stateId" access="field">
        <column name="stateId" sql-type="int" not-null="true"/>
      </key-property>
    </composite-id>


If I use openSession() instead of getCurrentSession() it works, but only up to the point when I do a saveOrUpdate(), where it throws a similar exception for a similar update setting primary keys to null.


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

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.