diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java
index e6f50a90d6..493743d172 100644
--- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java
+++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java
@@ -225,6 +225,8 @@ public class LocalSessionFactoryBuilder extends Configuration {
"Unknown transaction manager type: " + jtaTransactionManager.getClass().getName());
}
+ getProperties().put(AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY, "jta");
+
// Hibernate 5.1/5.2: manually enforce connection release mode AFTER_STATEMENT (the JTA default)
try {
// Try Hibernate 5.2
diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc
index ce97661743..bf27fbf13d 100644
--- a/src/docs/asciidoc/data-access.adoc
+++ b/src/docs/asciidoc/data-access.adoc
@@ -381,6 +381,19 @@ NOTE: The preceding definition of the `dataSource` bean uses the `
from the `jee` namespace. For more information see
<>.
+NOTE: If you use JTA, your transaction manager definition should look the same, regardless
+of what data access technology you use, be it JDBC, Hibernate JPA, or any other supported
+technology. This is due to the fact that JTA transactions are global transactions, which
+can enlist any transactional resource.
+
+In all Spring transaction setups, application code does not need to change. You can change
+how transactions are managed merely by changing configuration, even if that change means
+moving from local to global transactions or vice versa.
+
+
+[[transaction-strategies-hibernate]]
+==== Hibernate Transaction Setup
+
You can also easily use Hibernate local transactions, as shown in the following examples.
In this case, you need to define a Hibernate `LocalSessionFactoryBean`, which your
application code can use to obtain Hibernate `Session` instances.
@@ -420,21 +433,52 @@ example declares `sessionFactory` and `txManager` beans:
If you use Hibernate and Java EE container-managed JTA transactions, you should use the
same `JtaTransactionManager` as in the previous JTA example for JDBC, as the following
-example shows:
+example shows. Also, it is recommended to make Hibernate aware of JTA through its
+transaction coordinator and possibly also its connection release mode configuration:
[source,xml,indent=0,subs="verbatim,quotes"]
----
+
+
+
+
+ org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml
+
+
+
+
+ hibernate.dialect=${hibernate.dialect}
+ hibernate.transaction.coordinator_class=jta
+ hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT
+
+
+
+
----
-NOTE: If you use JTA, your transaction manager definition should look the same, regardless
-of what data access technology you use, be it JDBC, Hibernate JPA, or any other supported
-technology. This is due to the fact that JTA transactions are global transactions, which
-can enlist any transactional resource.
+Or alternatively, you may pass the `JtaTransactionManager` into your `LocalSessionFactoryBean`
+for enforcing the same defaults:
-In all these cases, application code does not need to change. You can change how
-transactions are managed merely by changing configuration, even if that change means
-moving from local to global transactions or vice versa.
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+ org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml
+
+
+
+
+ hibernate.dialect=${hibernate.dialect}
+
+
+
+
+
+
+----
@@ -3115,8 +3159,8 @@ hierarchy defined in the `org.springframework.dao` package. (See <`) and feed it, for example, to
- Spring's `JtaTransactionManager`, the easiest way is to specify a reference to
- the bean that defines this JTA `PlatformTransactionManager` instance as the value of the
- `jtaTransactionManager` property for `LocalSessionFactoryBean.` Spring then makes the
- object available to Hibernate.
-* More likely, you do not already have the JTA `PlatformTransactionManager` instance,
- because Spring's `JtaTransactionManager` can find it itself. Thus, you need to
- configure Hibernate to look up JTA `PlatformTransactionManager` directly. You do this
- by configuring an application server-specific `TransactionManagerLookup` class in the
- Hibernate configuration, as described in the Hibernate manual.
+You can resolve such issues by making Hibernate aware of the JTA transaction manager,
+to which it synchronizes (along with Spring). You have two options for doing this:
+
+* Pass your Spring `JtaTransactionManager` bean to your Hibernate setup. The easiest
+ way is a bean reference into the `jtaTransactionManager` property for your
+ `LocalSessionFactoryBean` bean (see <>).
+ Spring then makes the corresponding JTA strategies available to Hibernate.
+* You may also configure Hibernate's JTA-related properties explicitly, in particular
+ "hibernate.transaction.coordinator_class", "hibernate.connection.handling_mode"
+ and potentially "hibernate.transaction.jta.platform" in your "hibernateProperties"
+ on `LocalSessionFactoryBean` (see Hibernate's manual for details on those properties).
The remainder of this section describes the sequence of events that occur with and
without Hibernate's awareness of the JTA `PlatformTransactionManager`.
-When Hibernate is not configured with any awareness of the JTA
-`PlatformTransactionManager`, the following events occur when a JTA transaction commits:
+When Hibernate is not configured with any awareness of the JTA transaction manager,
+the following events occur when a JTA transaction commits:
* The JTA transaction commits.
* Spring's `JtaTransactionManager` is synchronized to the JTA transaction, so it is
@@ -7204,16 +7246,16 @@ When Hibernate is not configured with any awareness of the JTA
error, as the application server no longer considers the `Connection` to be usable,
because the transaction has already been committed.
-When Hibernate is configured with awareness of the JTA `PlatformTransactionManager`, the
-following events occur when a JTA transaction commits:
+When Hibernate is configured with awareness of the JTA transaction manager,
+the following events occur when a JTA transaction commits:
* The JTA transaction is ready to commit.
* Spring's `JtaTransactionManager` is synchronized to the JTA transaction, so the
transaction is called back through a `beforeCompletion` callback by the JTA
transaction manager.
* Spring is aware that Hibernate itself is synchronized to the JTA transaction and
- behaves differently than in the previous scenario. Assuming the Hibernate `Session`
- needs to be closed at all, Spring closes it now.
+ behaves differently than in the previous scenario. In particular, it aligns with
+ Hibernate's transactional resource management.
* The JTA transaction commits.
* Hibernate is synchronized to the JTA transaction, so the transaction is called back
through an `afterCompletion` callback by the JTA transaction manager and can
@@ -7244,13 +7286,13 @@ that is used by the application to obtain an entity manager.
[[orm-jpa-setup-lemfb]]
===== Using `LocalEntityManagerFactoryBean`
-You can use this option only in simple deployment environments such as stand-alone applications
-and integration tests.
+You can use this option only in simple deployment environments such as stand-alone
+applications and integration tests.
The `LocalEntityManagerFactoryBean` creates an `EntityManagerFactory` suitable for
-simple deployment environments where the application uses only JPA for data access. The
-factory bean uses the JPA `PersistenceProvider` auto-detection mechanism (according to
-JPA's Java SE bootstrapping) and, in most cases, requires you to specify only the
+simple deployment environments where the application uses only JPA for data access.
+The factory bean uses the JPA `PersistenceProvider` auto-detection mechanism (according
+to JPA's Java SE bootstrapping) and, in most cases, requires you to specify only the
persistence unit name. The following XML example configures such a bean:
[source,xml,indent=0,subs="verbatim,quotes"]
@@ -7734,7 +7776,7 @@ steps:
your transaction coordinator. This is usually straightforward in a Java EE environment,
exposing a different kind of `DataSource` through JNDI. See your application server
documentation for details. Analogously, a standalone transaction coordinator usually
-comes with special XA-integrated `DataSource` implementations. Again, check its documentation.
+comes with special XA-integrated `DataSource` variants. Again, check its documentation.
* The JPA `EntityManagerFactory` setup needs to be configured for JTA. This is
provider-specific, typically through special properties to be specified as `jpaProperties`
@@ -7743,11 +7785,11 @@ are even version-specific. See your Hibernate documentation for details.
* Spring's `HibernateJpaVendorAdapter` enforces certain Spring-oriented defaults, such
as the connection release mode, `on-close`, which matches Hibernate's own default in
-Hibernate 5.0 but not any more in 5.1/5.2. For a JTA setup, either do not declare
-`HibernateJpaVendorAdapter` to begin with or turn off its `prepareConnection` flag.
-Alternatively, set Hibernate 5.2's `hibernate.connection.handling_mode` property to
+Hibernate 5.0 but not any more in Hibernate 5.1+. For a JTA setup, make sure to declare
+your persistence unit transaction type as "JTA". Alternatively, set Hibernate 5.2's
+`hibernate.connection.handling_mode` property to
`DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT` to restore Hibernate's own default.
-See <> for a related note about WebLogic.
+See <> for related notes.
* Alternatively, consider obtaining the `EntityManagerFactory` from your application
server itself (that is, through a JNDI lookup instead of a locally declared