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.