@@ -381,6 +381,19 @@ NOTE: The preceding definition of the `dataSource` bean uses the `<jndi-lookup/>
381381from the `jee` namespace. For more information see
382382<<integration.adoc#xsd-schemas-jee, The JEE Schema>>.
383383
384+ NOTE: If you use JTA, your transaction manager definition should look the same, regardless
385+ of what data access technology you use, be it JDBC, Hibernate JPA, or any other supported
386+ technology. This is due to the fact that JTA transactions are global transactions, which
387+ can enlist any transactional resource.
388+
389+ In all Spring transaction setups, application code does not need to change. You can change
390+ how transactions are managed merely by changing configuration, even if that change means
391+ moving from local to global transactions or vice versa.
392+
393+
394+ [[transaction-strategies-hibernate]]
395+ ==== Hibernate Transaction Setup
396+
384397You can also easily use Hibernate local transactions, as shown in the following examples.
385398In this case, you need to define a Hibernate `LocalSessionFactoryBean`, which your
386399application code can use to obtain Hibernate `Session` instances.
@@ -420,21 +433,52 @@ example declares `sessionFactory` and `txManager` beans:
420433
421434If you use Hibernate and Java EE container-managed JTA transactions, you should use the
422435same `JtaTransactionManager` as in the previous JTA example for JDBC, as the following
423- example shows:
436+ example shows. Also, it is recommended to make Hibernate aware of JTA through its
437+ transaction coordinator and possibly also its connection release mode configuration:
424438
425439[source,xml,indent=0,subs="verbatim,quotes"]
426440----
441+ <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
442+ <property name="dataSource" ref="dataSource"/>
443+ <property name="mappingResources">
444+ <list>
445+ <value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
446+ </list>
447+ </property>
448+ <property name="hibernateProperties">
449+ <value>
450+ hibernate.dialect=${hibernate.dialect}
451+ hibernate.transaction.coordinator_class=jta
452+ hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT
453+ </value>
454+ </property>
455+ </bean>
456+
427457 <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
428458----
429459
430- NOTE: If you use JTA, your transaction manager definition should look the same, regardless
431- of what data access technology you use, be it JDBC, Hibernate JPA, or any other supported
432- technology. This is due to the fact that JTA transactions are global transactions, which
433- can enlist any transactional resource.
460+ Or alternatively, you may pass the `JtaTransactionManager` into your `LocalSessionFactoryBean`
461+ for enforcing the same defaults:
434462
435- In all these cases, application code does not need to change. You can change how
436- transactions are managed merely by changing configuration, even if that change means
437- moving from local to global transactions or vice versa.
463+ [source,xml,indent=0,subs="verbatim,quotes"]
464+ ----
465+ <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
466+ <property name="dataSource" ref="dataSource"/>
467+ <property name="mappingResources">
468+ <list>
469+ <value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
470+ </list>
471+ </property>
472+ <property name="hibernateProperties">
473+ <value>
474+ hibernate.dialect=${hibernate.dialect}
475+ </value>
476+ </property>
477+ <property name="jtaTransactionManager" ref="txManager"/>
478+ </bean>
479+
480+ <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
481+ ----
438482
439483
440484
@@ -3115,8 +3159,8 @@ hierarchy defined in the `org.springframework.dao` package. (See <<dao-exception
31153159
31163160When you use the `JdbcTemplate` for your code, you need only to implement callback
31173161interfaces, giving them a clearly defined contract. Given a `Connection` provided by the
3118- `JdbcTemplate` class, the `PreparedStatementCreator`
3119- callback interface creates a prepared statement, providing SQL and any necessary parameters. The same is true for the
3162+ `JdbcTemplate` class, the `PreparedStatementCreator` callback interface creates a prepared
3163+ statement, providing SQL and any necessary parameters. The same is true for the
31203164`CallableStatementCreator` interface, which creates callable statements. The
31213165`RowCallbackHandler` interface extracts values from each row of a `ResultSet`.
31223166
@@ -7156,12 +7200,12 @@ conjunction with EJBs.
71567200==== Spurious Application Server Warnings with Hibernate
71577201
71587202In some JTA environments with very strict `XADataSource` implementations (currently
7159- only some WebLogic Server and WebSphere versions), when Hibernate is configured without
7160- regard to the JTA `PlatformTransactionManager` object for that environment,
7161- spurious warning or exceptions can show up in the application server log.
7162- These warnings or exceptions indicate that the connection being accessed is no longer
7163- valid or JDBC access is no longer valid, possibly because the transaction is no longer
7164- active. As an example, here is an actual exception from WebLogic:
7203+ some WebLogic Server and WebSphere versions), when Hibernate is configured without
7204+ regard to the JTA transaction manager for that environment, spurious warnings or
7205+ exceptions can show up in the application server log. These warnings or exceptions
7206+ indicate that the connection being accessed is no longer valid or JDBC access is no
7207+ longer valid, possibly because the transaction is no longer active. As an example,
7208+ here is an actual exception from WebLogic:
71657209
71667210[literal]
71677211[subs="verbatim,quotes"]
@@ -7170,28 +7214,26 @@ java.sql.SQLException: The transaction is no longer active - status: 'Committed'
71707214further JDBC access is allowed within this transaction.
71717215----
71727216
7173- You can resolve this warning by making Hibernate aware of the JTA
7174- `PlatformTransactionManager` instance, to which it synchronizes (along with Spring).
7175- You have two options for doing this:
7217+ Another common problem is a connection leak after JTA transactions, with Hibernate
7218+ sessions (and potentially underlying JDBC connections) not getting closed properly.
7219+
7220+ You can resolve such issues by making Hibernate aware of the JTA transaction manager,
7221+ to which it synchronizes (along with Spring). You have two options for doing this:
71767222
7177- * If, in your application context, you already directly obtain the JTA
7178- `PlatformTransactionManager` object (presumably from JNDI through
7179- `JndiObjectFactoryBean` or `<jee:jndi-lookup>`) and feed it, for example, to
7180- Spring's `JtaTransactionManager`, the easiest way is to specify a reference to
7181- the bean that defines this JTA `PlatformTransactionManager` instance as the value of the
7182- `jtaTransactionManager` property for `LocalSessionFactoryBean.` Spring then makes the
7183- object available to Hibernate.
7184- * More likely, you do not already have the JTA `PlatformTransactionManager` instance,
7185- because Spring's `JtaTransactionManager` can find it itself. Thus, you need to
7186- configure Hibernate to look up JTA `PlatformTransactionManager` directly. You do this
7187- by configuring an application server-specific `TransactionManagerLookup` class in the
7188- Hibernate configuration, as described in the Hibernate manual.
7223+ * Pass your Spring `JtaTransactionManager` bean to your Hibernate setup. The easiest
7224+ way is a bean reference into the `jtaTransactionManager` property for your
7225+ `LocalSessionFactoryBean` bean (see <<transaction-strategies-hibernate>>).
7226+ Spring then makes the corresponding JTA strategies available to Hibernate.
7227+ * You may also configure Hibernate's JTA-related properties explicitly, in particular
7228+ "hibernate.transaction.coordinator_class", "hibernate.connection.handling_mode"
7229+ and potentially "hibernate.transaction.jta.platform" in your "hibernateProperties"
7230+ on `LocalSessionFactoryBean` (see Hibernate's manual for details on those properties).
71897231
71907232The remainder of this section describes the sequence of events that occur with and
71917233without Hibernate's awareness of the JTA `PlatformTransactionManager`.
71927234
7193- When Hibernate is not configured with any awareness of the JTA
7194- `PlatformTransactionManager`, the following events occur when a JTA transaction commits:
7235+ When Hibernate is not configured with any awareness of the JTA transaction manager,
7236+ the following events occur when a JTA transaction commits:
71957237
71967238* The JTA transaction commits.
71977239* 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
72047246 error, as the application server no longer considers the `Connection` to be usable,
72057247 because the transaction has already been committed.
72067248
7207- When Hibernate is configured with awareness of the JTA `PlatformTransactionManager`, the
7208- following events occur when a JTA transaction commits:
7249+ When Hibernate is configured with awareness of the JTA transaction manager,
7250+ the following events occur when a JTA transaction commits:
72097251
72107252* The JTA transaction is ready to commit.
72117253* Spring's `JtaTransactionManager` is synchronized to the JTA transaction, so the
72127254 transaction is called back through a `beforeCompletion` callback by the JTA
72137255 transaction manager.
72147256* Spring is aware that Hibernate itself is synchronized to the JTA transaction and
7215- behaves differently than in the previous scenario. Assuming the Hibernate `Session`
7216- needs to be closed at all, Spring closes it now .
7257+ behaves differently than in the previous scenario. In particular, it aligns with
7258+ Hibernate's transactional resource management .
72177259* The JTA transaction commits.
72187260* Hibernate is synchronized to the JTA transaction, so the transaction is called back
72197261 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.
72447286[[orm-jpa-setup-lemfb]]
72457287===== Using `LocalEntityManagerFactoryBean`
72467288
7247- You can use this option only in simple deployment environments such as stand-alone applications
7248- and integration tests.
7289+ You can use this option only in simple deployment environments such as stand-alone
7290+ applications and integration tests.
72497291
72507292The `LocalEntityManagerFactoryBean` creates an `EntityManagerFactory` suitable for
7251- simple deployment environments where the application uses only JPA for data access. The
7252- factory bean uses the JPA `PersistenceProvider` auto-detection mechanism (according to
7253- JPA's Java SE bootstrapping) and, in most cases, requires you to specify only the
7293+ simple deployment environments where the application uses only JPA for data access.
7294+ The factory bean uses the JPA `PersistenceProvider` auto-detection mechanism (according
7295+ to JPA's Java SE bootstrapping) and, in most cases, requires you to specify only the
72547296persistence unit name. The following XML example configures such a bean:
72557297
72567298[source,xml,indent=0,subs="verbatim,quotes"]
@@ -7734,7 +7776,7 @@ steps:
77347776your transaction coordinator. This is usually straightforward in a Java EE environment,
77357777exposing a different kind of `DataSource` through JNDI. See your application server
77367778documentation for details. Analogously, a standalone transaction coordinator usually
7737- comes with special XA-integrated `DataSource` implementations . Again, check its documentation.
7779+ comes with special XA-integrated `DataSource` variants . Again, check its documentation.
77387780
77397781* The JPA `EntityManagerFactory` setup needs to be configured for JTA. This is
77407782provider-specific, typically through special properties to be specified as `jpaProperties`
@@ -7743,11 +7785,11 @@ are even version-specific. See your Hibernate documentation for details.
77437785
77447786* Spring's `HibernateJpaVendorAdapter` enforces certain Spring-oriented defaults, such
77457787as the connection release mode, `on-close`, which matches Hibernate's own default in
7746- Hibernate 5.0 but not any more in 5.1/5.2. For a JTA setup, either do not declare
7747- `HibernateJpaVendorAdapter` to begin with or turn off its `prepareConnection` flag.
7748- Alternatively, set Hibernate 5.2's `hibernate.connection.handling_mode` property to
7788+ Hibernate 5.0 but not any more in Hibernate 5.1+. For a JTA setup, make sure to declare
7789+ your persistence unit transaction type as "JTA". Alternatively, set Hibernate 5.2's
7790+ `hibernate.connection.handling_mode` property to
77497791`DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT` to restore Hibernate's own default.
7750- See <<orm-hibernate-invalid-jdbc-access-error>> for a related note about WebLogic .
7792+ See <<orm-hibernate-invalid-jdbc-access-error>> for related notes .
77517793
77527794* Alternatively, consider obtaining the `EntityManagerFactory` from your application
77537795server itself (that is, through a JNDI lookup instead of a locally declared
0 commit comments