Chapter 13. Session and Transaction Handling

Table of Contents

Hibernate Session
JTA versus JDBC Transactions
Transaction handling – default pattern
JDBC transactions with ThreadLocal
JTA transaction with a single database
JDBC or JTA with the Spring framework
Conversations and Session Lifetime
Short life of a session
Lifetime until the view is rendered (Open-Session-in-View)
Long life of a session
Concurrent Access
Optimistic Locking

Before we discuss advantages and disadvantages in detail, I would state a general recommendation.

I recommend to use optimistic locking in combination with a short running session for most web applications. If you want to understand why then continue to read this chapter.

Hibernate Session

A session provides all methods to access the database and is at the same time a cache holding all data being used in a transaction. If you load objects using a query or if you save an object or just attach it to the session, than the object will be added to the Persistence Context of the session.

Persistence Context

Objects are continuously added to the persistence context of the session until you close the session. If you call session.get and the object already exists in the persistence context, then the object will not be retrieved from the database but from the context. Therefore, the session is called a first level cache.

There is one caveat with this behaviour. If you query a lot of objects, you might run out of memory if your session became to large. We will handle strategies for this caveat in the chapter performance.

All database access including read and write access should happen inside a transaction.

A session is not thread safe and should only be used by one thread. Usually this is guaranteed by the SessionFactory.

To conclude: A session is used by one user in his thread to write and read data inside of transactions.

Typical Session usage. 

Session session = HibernateSessionFactoryUtil.openSession();
session.beginTransaction();
// do something
session.save(myObject);
session.getTransaction().commit();
session.beginTransaction();
// do something else
List result = session.createQuery(
   "from Order o where o.invoice.number like '2%' ").list();
session.getTransaction().commit();
session.close();

Write behind behaviour

The session is not sending the SQL statements directly to the database, if you call session.save. There are a number of reasons for this behaviour:

  • keep write locks in the database as short as possible
  • more efficient sending of SQL statements
  • allow optimisations like JDBC batching

By the default configuration the SQL statements are flushed when

  • tx.commit is called
  • a query is executed for an Entity which has a insert/update/delete statement in the queue
  • session.flush is called explicitly

This is the reason why you might see no SQL statements when calling session.save.

There is an exception to this rule as well. If you use select or identity as id generator, it is required that Hibernate sends the insert immediately.