12.2.1. Unmanaged environment
If the Hibernat persistence layer is running in an unmanaged environment, the database connection is usually handled by the hibernate connection pooling mechanism.
代码内容
session/transaction处理方式如下所示:
//Non-managed environment idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}
You do not need an explicit flush () session-the call to commit () automatically triggers the synchronization of the sessions.
Call the Close () flag to end the session. The close () method is an important hint that the session frees the JDBC connection.
This Java code is portable and can be run in unmanaged and JTA environments.
It is likely that you have never seen such a usage in a standard application's business code; a fatal (System) exception should always be captured on the application "top level". In other words, the code that executes the hibernate call (at the persistence layer) and the code that handles the runtimeexception exception (usually only cleans and exits the application) should be at the different application logic layer. This is a challenge for you to design your own software system, so whenever possible, you should use the J2EE/EJB container service. Exception handling will be discussed later in this chapter.
Please note that you should select Org.hibernate.transaction.JDBCTransactionFactory (this is the default option).
12.2.2. Use JTA
If your persistence layer is running on an application server (for example, after the EJB session beans), each data source connection that hibernate obtains will automatically become part of the global JTA transaction. Hibernate provides two strategies for JTA integration.
If you use the Bean Management Transaction (BMT), you can tell the application server to start and end the BMT transaction by using the Hibernate Transaction API. Therefore, transaction management code is the same as in unmanaged environments.
代码内容
// BMT idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}
In the CMT mode, the transaction declaration is in the deployment descriptor of the session bean, and does not require programming. Unless you set the attribute hibernate.transaction.flush_before_completion and hibernate.transaction.auto_close_session to True, Otherwise you must synchronize and close the session yourself. Hibernate can automatically sync and close sessions for you. The only thing you have to do is rollback the transaction when an exception occurs. Fortunately, in a CMT Bean, a transaction rollback can even be done automatically by the container because an unhandled runtimeexception exception thrown by the session bean method notifies the container to set a global transaction rollback. This means that you do not have to use the Hibernate transaction API at all in CMT.
Please note that when you configure the Hibernate transaction factory, in a BMT session bean, you should choose Org.hibernate.transaction.JTATransactionFactory, in a CMT session Select Org.hibernate.transaction.CMTTransactionFactory in the Bean. Remember to set the Org.hibernate.transaction.manager_lookup_class as well.
If you use the CMT environment and have the container automatically sync and close the session, you may also want to use the same session in different parts of your code. In general, in an unmanaged environment, you can use a threadlocal variable to hold this session, but a single EJB method invocation might execute on a different thread (for example, a session bean calls another session bean). If you don't want to be bothered by the problem of passing the Session object instance in your application code, then the Getcurrentsession () method provided by Sessionfactory is good for you, and the method returns a session instance bound to the JTA transaction context. This is also the easiest way to integrate hibernate into an application! This "current" session can always be automatically synchronized and automatically closed (regardless of the property settings described above). Our Session/transaction management code is reduced to the following:
代码内容
// CMT idiom
Session sess = factory.getCurrentSession();
// do some work
...
In other words, in a managed environment, all you have to do is call Sessionfactory.getcurrentsession (), then do your data access, and give the rest of the work to the container. Transactions are set in a declarative manner in the deployment descriptor of your session bean. The life cycle of the session is managed entirely by hibernate.
There is a warning about how the After_statement connection is released. Because of a very stupid limitation of the JTA specification, hibernate cannot automatically clean up any scrollableresults or iterator that are not closed, which are generated by scroll () or iterate (). You must to release the underlying database cursor by explicitly calling the Scrollableresults.close () or Hibernate.close (iterator) method in the finally block. (Of course, most programs can easily avoid the presence of scroll () or iterate () in the CMT code. )