@@ -381,6 +381,19 @@ NOTE: The preceding definition of the `dataSource` bean uses the `<jndi-lookup/>
381
381
from the `jee` namespace. For more information see
382
382
<<integration.adoc#xsd-schemas-jee, The JEE Schema>>.
383
383
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
+
384
397
You can also easily use Hibernate local transactions, as shown in the following examples.
385
398
In this case, you need to define a Hibernate `LocalSessionFactoryBean`, which your
386
399
application code can use to obtain Hibernate `Session` instances.
@@ -420,21 +433,52 @@ example declares `sessionFactory` and `txManager` beans:
420
433
421
434
If you use Hibernate and Java EE container-managed JTA transactions, you should use the
422
435
same `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:
424
438
425
439
[source,xml,indent=0,subs="verbatim,quotes"]
426
440
----
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
+
427
457
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
428
458
----
429
459
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:
434
462
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
+ ----
438
482
439
483
440
484
@@ -3115,8 +3159,8 @@ hierarchy defined in the `org.springframework.dao` package. (See <<dao-exception
3115
3159
3116
3160
When you use the `JdbcTemplate` for your code, you need only to implement callback
3117
3161
interfaces, 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
3120
3164
`CallableStatementCreator` interface, which creates callable statements. The
3121
3165
`RowCallbackHandler` interface extracts values from each row of a `ResultSet`.
3122
3166
@@ -7156,12 +7200,12 @@ conjunction with EJBs.
7156
7200
==== Spurious Application Server Warnings with Hibernate
7157
7201
7158
7202
In 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:
7165
7209
7166
7210
[literal]
7167
7211
[subs="verbatim,quotes"]
@@ -7170,28 +7214,26 @@ java.sql.SQLException: The transaction is no longer active - status: 'Committed'
7170
7214
further JDBC access is allowed within this transaction.
7171
7215
----
7172
7216
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:
7176
7222
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).
7189
7231
7190
7232
The remainder of this section describes the sequence of events that occur with and
7191
7233
without Hibernate's awareness of the JTA `PlatformTransactionManager`.
7192
7234
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:
7195
7237
7196
7238
* The JTA transaction commits.
7197
7239
* 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
7204
7246
error, as the application server no longer considers the `Connection` to be usable,
7205
7247
because the transaction has already been committed.
7206
7248
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:
7209
7251
7210
7252
* The JTA transaction is ready to commit.
7211
7253
* Spring's `JtaTransactionManager` is synchronized to the JTA transaction, so the
7212
7254
transaction is called back through a `beforeCompletion` callback by the JTA
7213
7255
transaction manager.
7214
7256
* 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 .
7217
7259
* The JTA transaction commits.
7218
7260
* Hibernate is synchronized to the JTA transaction, so the transaction is called back
7219
7261
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.
7244
7286
[[orm-jpa-setup-lemfb]]
7245
7287
===== Using `LocalEntityManagerFactoryBean`
7246
7288
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.
7249
7291
7250
7292
The `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
7254
7296
persistence unit name. The following XML example configures such a bean:
7255
7297
7256
7298
[source,xml,indent=0,subs="verbatim,quotes"]
@@ -7734,7 +7776,7 @@ steps:
7734
7776
your transaction coordinator. This is usually straightforward in a Java EE environment,
7735
7777
exposing a different kind of `DataSource` through JNDI. See your application server
7736
7778
documentation 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.
7738
7780
7739
7781
* The JPA `EntityManagerFactory` setup needs to be configured for JTA. This is
7740
7782
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.
7743
7785
7744
7786
* Spring's `HibernateJpaVendorAdapter` enforces certain Spring-oriented defaults, such
7745
7787
as 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
7749
7791
`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 .
7751
7793
7752
7794
* Alternatively, consider obtaining the `EntityManagerFactory` from your application
7753
7795
server itself (that is, through a JNDI lookup instead of a locally declared
0 commit comments