tags:

views:

73

answers:

3

Here is a block of code in the Java Persistence with Hibernate book by Christian and Gavin,

    
Session session = getSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
// First step in the conversation
session.beginTransaction();
Item item = (Item) session.get(Item.class, new Long(123) );
session.getTransaction().commit();
// Second step in the conversation
session.beginTransaction();
Item newItem = new Item();
Long newId = (Long) session.save(newItem); // Triggers INSERT!
session.getTransaction().commit();
// Roll back the conversation!
session.close();//enter code here

I am confused that why the first step and second step need to be wrapped into two separate transactions? Since the flushmode is set manual here, no operations (suppose we ignore the insert here) will hit the database anyway. So why bother with transactions here?

thanks

A: 

I'm thinking it's because of persistence best-practice reasons. For example at

Long newId = (Long) session.save(newItem);

The item newItem won't be persisted to the database until the transaction is committed. And when "getting" an instance at

Item item = (Item) session.get(Item.class, new Long(123) );

the transaction is committed because get() will retrieve a persisted object. By committing the transaction item is detached from the transaction and will not be persisted (until explicitly updated and saved again).

More info on wiki

http://en.wikipedia.org/wiki/Object_database

http://en.wikipedia.org/wiki/Persistence_%28computer_science%29

Lars Andren
A: 

You must always have a running transaction when using hibernate.

And here is what the docs say about MANUAL:

This mode is very efficient for read only transactions.

As for the conversations - they are supposed to span more than one method (read here). So I don't think your example is supposed to be in one method.

As written in the article I linked, a transaction should be "a unit of work". If you find it necessary, use a new transaction. But be sure it is necessary. Otherwise - don't make multiple transactions in one request.

Bozho
thanks, but I still have the question (as I asked in the comment to Yuval's answer), do I need a transaction for each step in a conversation?
wei
@wei see updated
Bozho
A: 

As @Bozho says, this is mainly useful for read-only transactions. These are useful. They allow you to work with the same version of an object for two different purposes simultaneously, without harming the actual data. The Hibernate cache will bring you identical copies of the object in this case, and allow you to do whatever you want with them.

Yuval
thanks, the code above is copied from the chapter where the authors discuss how to implement conversation. so you mean the transaction here is only demonstrated for efficient read-only transactions? Here is actually what my question was, do I need a transaction for each step in a conversation?
wei
Basically, the answer is no, but that depends on the complexity of each step. If you have complex steps that must be atomic, a separate transaction is definitely relevant.
Yuval