diff --git a/reference/en/modules/configuration.xml b/reference/en/modules/configuration.xml
index 53cdf4bbe7..118021e827 100644
--- a/reference/en/modules/configuration.xml
+++ b/reference/en/modules/configuration.xml
@@ -1155,8 +1155,17 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]>
org.hibernate.transaction.JTATransactionFactory
- delegates to JTA (if an existing transaction is underway, the Session
- performs its work in that context, otherwise a new transaction is started)
+
+ delegates to JTA (if an existing transaction is underway, the
+ Session performs its work in that context, otherwise
+ a new transaction is started)
+
+
+
+
+ org.hibernate.transaction.CMTTransactionFactory
+
+ delegates to a container managed JTA transaction
diff --git a/reference/en/modules/transactions.xml b/reference/en/modules/transactions.xml
index 337313bde2..c89f8a0f12 100644
--- a/reference/en/modules/transactions.xml
+++ b/reference/en/modules/transactions.xml
@@ -334,8 +334,8 @@
However, it is often desirable to keep your persistence layer portable. Hibernate offers a wrapper
API called Transaction that translates into the native transaction system of
- your deployment environment. This API is optional (using database transactions is not!) and you don't
- have to use it if database portability provided by Hibernate is all you need.
+ your deployment environment. This API is actually optional, but we strongly encourage its use
+ unless you are in a CMT session bean.
@@ -376,43 +376,12 @@
If a Hibernate persistence layer runs in a non-managed environment, database connections
- are either handled by Hibernate's pooling mechanism or provided by the developer (this
- case has other implications, esp. with regard to caching):
+ are usually handled by Hibernate's pooling mechanism. The session/transaction handling
+ idiom looks like this:
-
-
-
- Note that you will very likely never see this piece of code in a normal application;
- fatal (system) exceptions should always be caught at the "top". In other words, the
- code that executes Hibernate calls (in the persistence layer) and the code that handles
- RuntimeException (and usually can only clean up and exit) are in
- different layers. This can be a challenge to design yourself and you should use J2EE/EJB
- container services whenever they are available. Exception handling is discussed later in
- this chapter.
-
-
-
- We recommend, even if persistence layer portability is not your primary concern, the
- Transaction API:
-
-
-
- Note that you don't have to flush() the Session
- explicitly, the call to commit() automatically triggers the
- synchronization. This piece of code is now portable and runs in non-managed and JTA
- environments. See for
- the configuration options of the Transaction API and how it can
- be mapped to the underlying resource transaction system.
+ You don't have to flush() the Session explicitly -
+ the call to commit() automatically triggers the synchronization.
A call to close() marks the end of a session. The main implication
- of close() is that the JDBC connection will be relinquished by the session.
- If you provided your own connection, close() returns a reference
- to it, so you can manually close it or return it to the pool. Otherwise close()
- returns it to the pool.
+ of close() is that the JDBC connection will be relinquished by the
+ session.
+
+ This Java code is portable and runs in both non-managed and JTA environments.
+
+
+
+ You will very likely never see this idiom in business code in a normal application;
+ fatal (system) exceptions should always be caught at the "top". In other words, the
+ code that executes Hibernate calls (in the persistence layer) and the code that handles
+ RuntimeException (and usually can only clean up and exit) are in
+ different layers. This can be a challenge to design yourself and you should use J2EE/EJB
+ container services whenever they are available. Exception handling is discussed later in
+ this chapter.
+
+
+
+ Note that you should choose org.hibernate.transaction.JDBCTransaction.
+
+
@@ -455,28 +436,72 @@ finally {
If your persistence layer runs in an application server (e.g. behind EJB session beans),
transaction boundaries are defined in deployment descriptors. Every datasource connection
- obtained by Hibernate will automatically be part of a global JTA transaction. Hibernate
+ obtained by Hibernate will automatically be part of the global JTA transaction. Hibernate
simply joins this transaction, or if a particular session bean method has no mandatory
- transaction, Hibernate will tell the application server to start and end a transaction
- directly. (The latter should be considered a very rare case and is offered for consistency
- reasons. Note that your container might not allow mixed CMT and BMT behavior.)
+ transaction, Hibernate will tell the application server to start and end a BMT transaction
+ directly. So, for BMT, the session handling idiom is identical to case of a non-managed
+ environment:
+
+
+
+
+
+ Note that you should choose org.hibernate.transaction.JTATransaction
+ in a BMT session bean, and org.hibernate.transaction.CMTTransaction
+ in a CMT session bean.
If you set the properties hibernate.transaction.flush_before_completion
and hibernate.transaction.auto_close_session to true,
- Hibernate wil also automatically flush and close the Session for you.
- The only thing left is exception handling and rollback of the database transaction.
- Fortunately, even this happens automatically, since an unhandled RuntimeException
+ Hibernate will automatically flush and close the Session for you.
+ The only thing left to rollback the transaction when an exception occurs. Fortunately, in
+ a CMT bean, even this happens automatically, since an unhandled RuntimeException
thrown by a session bean method tells the container to set the global transaction to
- rollback.
+ rollback. This means you do not need to use the Hibernate
+ Transaction API at all in CMT.
+
+
+
+ If you don't want to bother passing your Session instance around, the
+ SessionFactory provides the getCurrentSession()
+ method, which returns a session that is bound to the JTA transaction context. This is the
+ easiest way to integrate Hibernate into an application! The "current" session always has
+ auto-flush and auto-close enabled (regardless of the above property settings). Our
+ session/transaction management idiom is reduced to this:
+
+
- In other words, all you have to do in a managed environment is to get a Session
- from the SessionFactory (usually bound to JNDI), do your data access
- work, and leave the rest to the container. Transaction boundaries are set declaratively in
- the deployment descriptors of your session bean.
+ In other words, all you have to do in a managed environment is call
+ SessionFactory.getCurrentSession(), do your data access work, and leave
+ the rest to the container. Transaction boundaries are set declaratively in the deployment
+ descriptors of your session bean. The lifecycle of the session is completely managed by
+ Hibernate.