HowTo use Hibernate Sessions
From SONIVIS:Wiki
This article is intended to inform SONIVIS:Developers on the use of Hibernate Sessions when writing code for SONIVIS:Tool.
In general, we strongly recommend to use the Data Access Objects (DAOs) provided in the package de.sonivis.tool.core.datamodel.dao.spring.hibernate. These offer a wide range of standard operations, such as loading, storing, updating, and deleting data.
For more sophisticated queries that are not covered by the standard DAO methods, there exists a special method for each DAO class that takes a, s.c., Criteria Query. To learn more on Criteria Queries you may want to check our HowTo on these.
Unfortunately, it is not possible to cover any special case one could think of. Therefore - and it should be rarely necessary to be used -, you find information on proper session handling when writing code for SONIVIS.
Contents |
Standard usage
If one happens to require very specific access to the persistence layer he or she should know at least about some standard way how to use the Hibernate Session.
The following code snippet is a standard frame around the actual operations you want to do within a Hibernate Session.
01 Session session = null;
02 Transaction tx = null;
03 try {
04 session = ModelManager.getInstance().getCurrentSession();
05 tx = session.beginTransaction();
06
07 // do some work
08
09 tx.commit();
10 } catch (HibernateException he) {
11 tx.rollback();
12 he.printStackTrace();
13
14 // error handling
15 throw he;
16 } catch (CannotConnectToDatabaseException cctde) {
17 // error handling
18 throw cctde;
19 } finally {
20 session.close();
21 }
It is, in general, useful to obtain a separate org.hibernate.Session instance (line 04) since you will need it for almost any operation you are to do in the do some work part (line 07). But you are not required to do so - but in most cases will cause you more code to write.
Having the org.hibernate.Transaction (line 02) at hand is also convenient but not necessary. You could rewrite the above snippet as
Session session = null;
try {
session = ModelManager.getInstance().getCurrentSession();
session.beginTransaction();
// do some work
session.getTransaction().commit();
} catch (HibernateException he) {
session.getTransaction().rollback();
// error handling
} catch (CannotConnectToDatabaseException cctde) {
// error handling
} finally {
session.close();
}
Hibernate will take care of the transaction management and return the Transaction object that is connected with the session. This should also make clear that you cannot have two transactions open at the same time.
To gain the control on what's actually happening and where enclose the transaction in a try-catch-block (lines 03-19). HibernateExceptions are intended to indicate an unrecoverable error that should be handled immediately. The first action to take in the catch-block is to rollback the transaction (line 11) so that the persistence layer remains in a consistent state. You may then print some error information. In general it is a good idea to re-throw the caught exception but this might depend on the special requirements of the situation.
One should always be aware that the committing of the transaction (line 09) makes Hibernate execute the commands you asked it to do. It is a good idea to stick to the requirements of Java program logic when writing the code within the transaction and not to worry too much about SQL statements. Hibernate will serve very well to prevent errors from happening. I.e., it guarantees that there will be no foreign key violations. Therefore, it re-orders the SQL statements it creates and executes.
Special cases
Flushing the session
If for some reason you feel you need some interaction with the persistence layer to be executed immediately call session.flush(). The operations that have piled up since the beginTransaction() statement are brought to the persistence layer in that very moment.
Dos and Donts
After commit
After the Transaction.commit() statement there is no need to care about the session anymore. Since Hibernate works transaction-oriented, committing is the step to finalize your action. Hibernate takes care of the rest. The SONIVIS Hibernate configuration is set up to take back the freed connection into its pool after the transaction is committed.
Make it a convenience to explicitly close a session within the code through a call to Session.close() in the finally block of the exception handling (or anywhere else as appropriate). Although, the current configuration works transaction based it might be subject to change in the future. Closing a session explicitly does no harm and is therefore more future-proof..
Reusing a session
If you need to do several transactions shortly after each other it is generally a good idea to request a new session everytime. You can very well wrap a loop that requires persistence layer access in an open session and let it use a transaction for each single step.
Session session = null;
Transaction tx = null;
try {
session = ModelManager.getInstance().getCurrentSession();
tx = session.beginTransaction();
// do some work
tx.commit();
} catch (HibernateException he) {
tx.rollback();
// error handling
} catch (CannotConnectToDatabaseException cctde) {
// error handling
} finally {
session.close();
}
// do other stuff
try {
session = ModelManager.getInstance().getCurrentSession();
tx = session.beginTransaction();
// do some work
tx.commit();
} catch (HibernateException he) {
tx.rollback();
// error handling
} catch (CannotConnectToDatabaseException cctde) {
// error handling
} finally {
session.close();
}
// done with transactions
// go on
SessionFactory
In SONIVIS:Tool there is no need to set up an own SessionFactory. At first, this is a quite expensive operation. Second, the ModelManager provides you with an appropriately configured SessionFactory if need be. So just never create your own.
If you just have a couple of session related operations it should be sufficient to request the ModelManager's current session. It is taken care of that a session is actually provided.
An adequate case to request the ModelManager's SessionFactory would be if you create a class that uses sessions intensively and pretty often. Otherwise simply stay with the lightweight session.
Links
- Javadoc API for Hibernate Session
- Javadoc API for Hibernate SessionFactory
- Javadoc API for Hibernate Transaction
- Hibernate documentation on Configuration, i.e. for creating a SessionFactory
- Hibernate documentation on Working with objects (contains a lot on working with sessions, too)
- Hibernate documentation on Transactions And Concurrency

