springframework/springframework-3.2.18-hibernate4.3.patch
2020-06-09 15:16:34 +08:00

650 lines
30 KiB
Diff

diff -Nru spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java
--- spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java 2016-12-21 19:42:08.000000000 +0100
+++ spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/ConfigurableJtaPlatform.java 2016-12-22 20:34:41.500296971 +0100
@@ -16,60 +16,133 @@
package org.springframework.orm.hibernate4;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.UserTransaction;
-import org.hibernate.service.jta.platform.internal.AbstractJtaPlatform;
+import org.hibernate.TransactionException;
+import org.hibernate.service.Service;
import org.springframework.transaction.jta.UserTransactionAdapter;
import org.springframework.util.Assert;
/**
- * Implementation of Hibernate 4's {@link org.hibernate.service.jta.platform.spi.JtaPlatform}
- * SPI, exposing passed-in {@link TransactionManager} and {@link UserTransaction} references.
+ * Implementation of Hibernate 4's JtaPlatform SPI (which has a different package
+ * location in Hibernate 4.0-4.2 vs 4.3), exposing passed-in {@link TransactionManager},
+ * {@link UserTransaction} and {@link TransactionSynchronizationRegistry} references.
*
* @author Juergen Hoeller
* @since 3.1.2
*/
-@SuppressWarnings("serial")
-class ConfigurableJtaPlatform extends AbstractJtaPlatform {
+@SuppressWarnings({"serial", "unchecked"})
+class ConfigurableJtaPlatform implements InvocationHandler {
+
+ static final Class<? extends Service> jtaPlatformClass;
+
+ static {
+ Class<?> jpClass;
+ try {
+ // Try Hibernate 4.0-4.2 JtaPlatform variant
+ jpClass = SpringSessionContext.class.getClassLoader().loadClass(
+ "org.hibernate.service.jta.platform.spi.JtaPlatform");
+ }
+ catch (ClassNotFoundException ex) {
+ try {
+ // Try Hibernate 4.3 JtaPlatform variant
+ jpClass = SpringSessionContext.class.getClassLoader().loadClass(
+ "org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform");
+ }
+ catch (ClassNotFoundException ex2) {
+ throw new IllegalStateException("Neither Hibernate 4.0-4.2 nor 4.3 variant of JtaPlatform found");
+ }
+ }
+ jtaPlatformClass = (Class<? extends Service>) jpClass;
+ }
+
+ static String getJtaPlatformBasePackage() {
+ String className = jtaPlatformClass.getName();
+ return className.substring(0, className.length() - "spi.JtaPlatform".length());
+ }
private final TransactionManager transactionManager;
private final UserTransaction userTransaction;
+ private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
/**
* Create a new ConfigurableJtaPlatform instance with the given
* JTA TransactionManager and optionally a given UserTransaction.
* @param tm the JTA TransactionManager reference (required)
* @param ut the JTA UserTransaction reference (optional)
+ * @param tsr the JTA 1.1 TransactionSynchronizationRegistry (optional)
*/
- public ConfigurableJtaPlatform(TransactionManager tm, UserTransaction ut) {
+ public ConfigurableJtaPlatform(TransactionManager tm, UserTransaction ut, TransactionSynchronizationRegistry tsr) {
Assert.notNull(tm, "TransactionManager reference must not be null");
this.transactionManager = tm;
this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm));
+ this.transactionSynchronizationRegistry = tsr;
}
- @Override
- protected TransactionManager locateTransactionManager() {
+ public TransactionManager retrieveTransactionManager() {
return this.transactionManager;
}
- @Override
- protected UserTransaction locateUserTransaction() {
+ public UserTransaction retrieveUserTransaction() {
return this.userTransaction;
}
- @Override
- protected boolean canCacheTransactionManager() {
- return true;
+ public Object getTransactionIdentifier(Transaction transaction) {
+ return transaction;
+ }
+
+ public boolean canRegisterSynchronization() {
+ try {
+ return (this.transactionManager.getStatus() == Status.STATUS_ACTIVE);
+ }
+ catch (SystemException ex) {
+ throw new TransactionException("Could not determine JTA transaction status", ex);
+ }
+ }
+
+ public void registerSynchronization(Synchronization synchronization) {
+ if (this.transactionSynchronizationRegistry != null) {
+ this.transactionSynchronizationRegistry.registerInterposedSynchronization(synchronization);
+ }
+ else {
+ try {
+ this.transactionManager.getTransaction().registerSynchronization(synchronization);
+ }
+ catch (Exception ex) {
+ throw new TransactionException("Could not access JTA Transaction to register synchronization", ex);
+ }
+ }
+ }
+
+ public int getCurrentStatus() throws SystemException {
+ return this.transactionManager.getStatus();
}
- @Override
- protected boolean canCacheUserTransaction() {
- return true;
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Method targetMethod = getClass().getMethod(method.getName(), method.getParameterTypes());
+ return targetMethod.invoke(this, args);
}
+ /**
+ * Obtain a proxy that implements the current Hibernate version's JtaPlatform interface
+ * in the right package location, delegating all invocations to the same-named methods
+ * on this ConfigurableJtaPlatform class itself.
+ */
+ public Object getJtaPlatformProxy() {
+ return Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] {jtaPlatformClass}, this);
+ }
+
}
diff -Nru spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java
--- spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java 2016-12-21 19:42:08.000000000 +0100
+++ spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java 2016-12-22 20:38:31.548142550 +0100
@@ -30,7 +30,6 @@
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
-import org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -127,7 +126,7 @@
* instructing Hibernate to interact with externally managed transactions.
* <p>A passed-in Spring {@link JtaTransactionManager} needs to contain a JTA
* {@link TransactionManager} reference to be usable here, except for the WebSphere
- * case where we'll automatically set {@link WebSphereExtendedJtaPlatform} accordingly.
+ * case where we'll automatically set {@code WebSphereExtendedJtaPlatform} accordingly.
* <p>Note: If this is set, the Hibernate settings should not contain a JTA platform
* setting to avoid meaningless double configuration.
*/
@@ -136,7 +135,8 @@
if (jtaTransactionManager instanceof JtaTransactionManager) {
boolean webspherePresent = ClassUtils.isPresent("com.ibm.wsspi.uow.UOWManager", getClass().getClassLoader());
if (webspherePresent) {
- getProperties().put(AvailableSettings.JTA_PLATFORM, new WebSphereExtendedJtaPlatform());
+ getProperties().put(AvailableSettings.JTA_PLATFORM,
+ ConfigurableJtaPlatform.getJtaPlatformBasePackage() + "internal.WebSphereExtendedJtaPlatform");
}
else {
JtaTransactionManager jtaTm = (JtaTransactionManager) jtaTransactionManager;
@@ -145,12 +145,13 @@
"Can only apply JtaTransactionManager which has a TransactionManager reference set");
}
getProperties().put(AvailableSettings.JTA_PLATFORM,
- new ConfigurableJtaPlatform(jtaTm.getTransactionManager(), jtaTm.getUserTransaction()));
+ new ConfigurableJtaPlatform(jtaTm.getTransactionManager(), jtaTm.getUserTransaction(),
+ jtaTm.getTransactionSynchronizationRegistry()).getJtaPlatformProxy());
}
}
else if (jtaTransactionManager instanceof TransactionManager) {
getProperties().put(AvailableSettings.JTA_PLATFORM,
- new ConfigurableJtaPlatform((TransactionManager) jtaTransactionManager, null));
+ new ConfigurableJtaPlatform((TransactionManager) jtaTransactionManager, null, null).getJtaPlatformProxy());
}
else {
throw new IllegalArgumentException(
diff -Nru spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java
--- spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java 2016-12-21 19:42:08.000000000 +0100
+++ spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SessionFactoryUtils.java 2016-12-23 10:44:05.095253068 +0100
@@ -16,6 +16,7 @@
package org.springframework.orm.hibernate4;
+import java.lang.reflect.Method;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
@@ -41,7 +42,7 @@
import org.hibernate.exception.JDBCConnectionException;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.SQLGrammarException;
-import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.spi.Wrapped;
import org.springframework.dao.CannotAcquireLockException;
import org.springframework.dao.DataAccessException;
@@ -52,6 +53,8 @@
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ReflectionUtils;
/**
* Helper class featuring methods for Hibernate Session handling.
@@ -78,6 +81,11 @@
static final Log logger = LogFactory.getLog(SessionFactoryUtils.class);
+ /**
+ * Bridging between the different ConnectionProvider package location in 4.0-4.2 vs 4.3.
+ */
+ private static final Method getConnectionProviderMethod =
+ ClassUtils.getMethodIfAvailable(SessionFactoryImplementor.class, "getConnectionProvider");
/**
* Determine the DataSource of the given SessionFactory.
@@ -86,8 +94,8 @@
* @see org.hibernate.engine.spi.SessionFactoryImplementor#getConnectionProvider
*/
public static DataSource getDataSource(SessionFactory sessionFactory) {
- if (sessionFactory instanceof SessionFactoryImplementor) {
- ConnectionProvider cp = ((SessionFactoryImplementor) sessionFactory).getConnectionProvider();
+ if (getConnectionProviderMethod != null && sessionFactory instanceof SessionFactoryImplementor) {
+ Wrapped cp = (Wrapped) ReflectionUtils.invokeMethod(getConnectionProviderMethod, sessionFactory);
return cp.unwrap(DataSource.class);
}
return null;
diff -Nru spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java
--- spring-framework-3.2.18.RELEASE/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java 2016-12-21 19:42:08.000000000 +0100
+++ spring-framework-3.2.18.RELEASE.hibernate4.3/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/SpringSessionContext.java 2016-12-22 20:45:06.119514785 +0100
@@ -16,16 +16,16 @@
package org.springframework.orm.hibernate4;
-import javax.transaction.TransactionManager;
+import java.lang.reflect.Method;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.context.spi.CurrentSessionContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
-import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.springframework.transaction.support.TransactionSynchronizationManager;
+import org.springframework.util.ReflectionUtils;
/**
* Implementation of Hibernate 3.1's CurrentSessionContext interface
@@ -44,7 +44,7 @@
private final SessionFactoryImplementor sessionFactory;
- private final CurrentSessionContext jtaSessionContext;
+ private CurrentSessionContext jtaSessionContext;
/**
@@ -53,15 +53,24 @@
*/
public SpringSessionContext(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
- JtaPlatform jtaPlatform = sessionFactory.getServiceRegistry().getService(JtaPlatform.class);
- TransactionManager transactionManager = jtaPlatform.retrieveTransactionManager();
- this.jtaSessionContext = (transactionManager != null ? new SpringJtaSessionContext(sessionFactory) : null);
+ try {
+ Object jtaPlatform = sessionFactory.getServiceRegistry().getService(ConfigurableJtaPlatform.jtaPlatformClass);
+ Method rtmMethod = ConfigurableJtaPlatform.jtaPlatformClass.getMethod("retrieveTransactionManager");
+ Object transactionManager = ReflectionUtils.invokeMethod(rtmMethod, jtaPlatform);
+ if (transactionManager != null) {
+ this.jtaSessionContext = new SpringJtaSessionContext(sessionFactory);
+ }
+ }
+ catch (Exception ex) {
+ throw new IllegalStateException("Could not introspect Hibernate JtaPlatform for SpringJtaSessionContext", ex);
+ }
}
/**
* Retrieve the Spring-managed Session for the current thread, if any.
*/
+ @Override
public Session currentSession() throws HibernateException {
Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
if (value instanceof Session) {
@@ -70,15 +79,15 @@
else if (value instanceof SessionHolder) {
SessionHolder sessionHolder = (SessionHolder) value;
Session session = sessionHolder.getSession();
- if (!sessionHolder.isSynchronizedWithTransaction() &&
- TransactionSynchronizationManager.isSynchronizationActive()) {
+ if (TransactionSynchronizationManager.isSynchronizationActive() &&
+ !sessionHolder.isSynchronizedWithTransaction()) {
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, this.sessionFactory));
sessionHolder.setSynchronizedWithTransaction(true);
// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
// with FlushMode.MANUAL, which needs to allow flushing within the transaction.
FlushMode flushMode = session.getFlushMode();
- if (FlushMode.isManualFlushMode(flushMode) &&
+ if (flushMode.equals(FlushMode.MANUAL) &&
!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.AUTO);
sessionHolder.setPreviousFlushMode(flushMode);
diff -Nru spring-framework-3.2.18.RELEASE/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java spring-framework-3.2.18.RELEASE.hibernate4.3/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java
--- spring-framework-3.2.18.RELEASE/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java 2016-12-21 19:42:08.000000000 +0100
+++ spring-framework-3.2.18.RELEASE.hibernate4.3/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java 2016-12-22 21:08:45.109820257 +0100
@@ -28,7 +28,6 @@
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
-import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
@@ -50,7 +49,6 @@
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -101,8 +99,8 @@
* JtaTransactionManager autodetects the TransactionSynchronizationRegistry and uses
* it for registering Spring-managed synchronizations when participating in an existing
* JTA transaction (e.g. controlled by EJB CMT). If no TransactionSynchronizationRegistry
- * is available (or the JTA 1.1 API isn't available), then such synchronizations will be
- * registered via the (non-EE) JTA TransactionManager handle.
+ * is available, then such synchronizations will be registered via the (non-EE) JTA
+ * TransactionManager handle.
*
* <p>This class is serializable. However, active synchronizations do not survive serialization.
*
@@ -148,22 +146,6 @@
"java:comp/TransactionSynchronizationRegistry";
- private static final String TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME =
- "javax.transaction.TransactionSynchronizationRegistry";
-
- private static Class<?> transactionSynchronizationRegistryClass;
-
- static {
- try {
- transactionSynchronizationRegistryClass = ClassUtils.forName(
- TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME, JtaTransactionManager.class.getClassLoader());
- }
- catch (ClassNotFoundException ex) {
- // JTA 1.1 API not available... simply proceed the JTA 1.0 way.
- }
- }
-
-
private transient JndiTemplate jndiTemplate = new JndiTemplate();
private transient UserTransaction userTransaction;
@@ -182,9 +164,11 @@
private boolean autodetectTransactionManager = true;
+ private transient TransactionSynchronizationRegistry transactionSynchronizationRegistry;
+
private String transactionSynchronizationRegistryName;
- private transient Object transactionSynchronizationRegistry;
+ private boolean autodetectTransactionSynchronizationRegistry = true;
private boolean allowCustomIsolationLevels = false;
@@ -352,6 +336,28 @@
}
/**
+ * Set the JTA 1.1 TransactionSynchronizationRegistry to use as direct reference.
+ * <p>A TransactionSynchronizationRegistry allows for interposed registration
+ * of transaction synchronizations, as an alternative to the regular registration
+ * methods on the JTA TransactionManager API. Also, it is an official part of the
+ * Java EE 5 platform, in contrast to the JTA TransactionManager itself.
+ * <p>Note that the TransactionSynchronizationRegistry will be autodetected in JNDI and
+ * also from the UserTransaction/TransactionManager object if implemented there as well.
+ * @see #setTransactionSynchronizationRegistryName
+ * @see #setAutodetectTransactionSynchronizationRegistry
+ */
+ public void setTransactionSynchronizationRegistry(TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
+ this.transactionSynchronizationRegistry = transactionSynchronizationRegistry;
+ }
+
+ /**
+ * Return the JTA 1.1 TransactionSynchronizationRegistry that this transaction manager uses, if any.
+ */
+ public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
+ return this.transactionSynchronizationRegistry;
+ }
+
+ /**
* Set the JNDI name of the JTA TransactionManager.
* <p>A TransactionManager is necessary for suspending and resuming transactions,
* as this not supported by the UserTransaction interface.
@@ -393,6 +399,20 @@
}
/**
+ * Set whether to autodetect a JTA 1.1 TransactionSynchronizationRegistry object
+ * at its default JDNI location ("java:comp/TransactionSynchronizationRegistry")
+ * if the UserTransaction has also been obtained from JNDI, and also whether
+ * to fall back to checking whether the JTA UserTransaction/TransactionManager
+ * object implements the JTA TransactionSynchronizationRegistry interface too.
+ * <p>Default is "true", autodetecting the TransactionSynchronizationRegistry
+ * unless it has been specified explicitly. Can be turned off to delegate
+ * synchronization registration to the regular JTA TransactionManager API.
+ */
+ public void setAutodetectTransactionSynchronizationRegistry(boolean autodetectTransactionSynchronizationRegistry) {
+ this.autodetectTransactionSynchronizationRegistry = autodetectTransactionSynchronizationRegistry;
+ }
+
+ /**
* Set whether to allow custom isolation levels to be specified.
* <p>Default is "false", throwing an exception if a non-default isolation level
* is specified for a transaction. Turn this flag on if affected resource adapters
@@ -410,6 +430,7 @@
* Initialize the UserTransaction as well as the TransactionManager handle.
* @see #initUserTransactionAndTransactionManager()
*/
+ @Override
public void afterPropertiesSet() throws TransactionSystemException {
initUserTransactionAndTransactionManager();
checkUserTransactionAndTransactionManager();
@@ -421,38 +442,36 @@
* @throws TransactionSystemException if initialization failed
*/
protected void initUserTransactionAndTransactionManager() throws TransactionSystemException {
- // Fetch JTA UserTransaction from JNDI, if necessary.
if (this.userTransaction == null) {
+ // Fetch JTA UserTransaction from JNDI, if necessary.
if (StringUtils.hasLength(this.userTransactionName)) {
this.userTransaction = lookupUserTransaction(this.userTransactionName);
this.userTransactionObtainedFromJndi = true;
}
else {
this.userTransaction = retrieveUserTransaction();
+ if (this.userTransaction == null && this.autodetectUserTransaction) {
+ // Autodetect UserTransaction at its default JNDI location.
+ this.userTransaction = findUserTransaction();
+ }
}
}
- // Fetch JTA TransactionManager from JNDI, if necessary.
if (this.transactionManager == null) {
+ // Fetch JTA TransactionManager from JNDI, if necessary.
if (StringUtils.hasLength(this.transactionManagerName)) {
this.transactionManager = lookupTransactionManager(this.transactionManagerName);
}
else {
this.transactionManager = retrieveTransactionManager();
+ if (this.transactionManager == null && this.autodetectTransactionManager) {
+ // Autodetect UserTransaction object that implements TransactionManager,
+ // and check fallback JNDI locations otherwise.
+ this.transactionManager = findTransactionManager(this.userTransaction);
+ }
}
}
- // Autodetect UserTransaction at its default JNDI location.
- if (this.userTransaction == null && this.autodetectUserTransaction) {
- this.userTransaction = findUserTransaction();
- }
-
- // Autodetect UserTransaction object that implements TransactionManager,
- // and check fallback JNDI locations otherwise.
- if (this.transactionManager == null && this.autodetectTransactionManager) {
- this.transactionManager = findTransactionManager(this.userTransaction);
- }
-
// If only JTA TransactionManager specified, create UserTransaction handle for it.
if (this.userTransaction == null && this.transactionManager != null) {
this.userTransaction = buildUserTransaction(this.transactionManager);
@@ -494,15 +513,20 @@
* @throws TransactionSystemException if initialization failed
*/
protected void initTransactionSynchronizationRegistry() {
- if (StringUtils.hasLength(this.transactionSynchronizationRegistryName)) {
- this.transactionSynchronizationRegistry =
- lookupTransactionSynchronizationRegistry(this.transactionSynchronizationRegistryName);
- }
- else {
- this.transactionSynchronizationRegistry = retrieveTransactionSynchronizationRegistry();
- if (this.transactionSynchronizationRegistry == null) {
+ if (this.transactionSynchronizationRegistry == null) {
+ // Fetch JTA TransactionSynchronizationRegistry from JNDI, if necessary.
+ if (StringUtils.hasLength(this.transactionSynchronizationRegistryName)) {
this.transactionSynchronizationRegistry =
- findTransactionSynchronizationRegistry(this.userTransaction, this.transactionManager);
+ lookupTransactionSynchronizationRegistry(this.transactionSynchronizationRegistryName);
+ }
+ else {
+ this.transactionSynchronizationRegistry = retrieveTransactionSynchronizationRegistry();
+ if (this.transactionSynchronizationRegistry == null && this.autodetectTransactionSynchronizationRegistry) {
+ // Autodetect in JNDI if applicable, and check UserTransaction/TransactionManager
+ // object that implements TransactionSynchronizationRegistry otherwise.
+ this.transactionSynchronizationRegistry =
+ findTransactionSynchronizationRegistry(this.userTransaction, this.transactionManager);
+ }
}
}
@@ -586,16 +610,12 @@
* @see #setJndiTemplate
* @see #setTransactionSynchronizationRegistryName
*/
- protected Object lookupTransactionSynchronizationRegistry(String registryName) throws TransactionSystemException {
- if (transactionSynchronizationRegistryClass == null) {
- throw new TransactionSystemException(
- "JTA 1.1 [" + TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME + "] API not available");
- }
+ protected TransactionSynchronizationRegistry lookupTransactionSynchronizationRegistry(String registryName) throws TransactionSystemException {
try {
if (logger.isDebugEnabled()) {
logger.debug("Retrieving JTA TransactionSynchronizationRegistry from JNDI location [" + registryName + "]");
}
- return getJndiTemplate().lookup(registryName, transactionSynchronizationRegistryClass);
+ return getJndiTemplate().lookup(registryName, TransactionSynchronizationRegistry.class);
}
catch (NamingException ex) {
throw new TransactionSystemException(
@@ -637,7 +657,7 @@
* or {@code null} if none found
* @throws TransactionSystemException in case of errors
*/
- protected Object retrieveTransactionSynchronizationRegistry() throws TransactionSystemException {
+ protected TransactionSynchronizationRegistry retrieveTransactionSynchronizationRegistry() throws TransactionSystemException {
return null;
}
@@ -712,24 +732,15 @@
* or {@code null} if none found
* @throws TransactionSystemException in case of errors
*/
- protected Object findTransactionSynchronizationRegistry(UserTransaction ut, TransactionManager tm)
+ protected TransactionSynchronizationRegistry findTransactionSynchronizationRegistry(UserTransaction ut, TransactionManager tm)
throws TransactionSystemException {
- if (transactionSynchronizationRegistryClass == null) {
- // JTA 1.1 API not present - skip.
- if (logger.isDebugEnabled()) {
- logger.debug("JTA 1.1 [" + TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME + "] API not available");
- }
- return null;
- }
-
- // If we came here, we might be on Java EE 5, since the JTA 1.1 API is present.
if (this.userTransactionObtainedFromJndi) {
// UserTransaction has already been obtained from JNDI, so the
// TransactionSynchronizationRegistry probably sits there as well.
String jndiName = DEFAULT_TRANSACTION_SYNCHRONIZATION_REGISTRY_NAME;
try {
- Object tsr = getJndiTemplate().lookup(jndiName, transactionSynchronizationRegistryClass);
+ TransactionSynchronizationRegistry tsr = getJndiTemplate().lookup(jndiName, TransactionSynchronizationRegistry.class);
if (logger.isDebugEnabled()) {
logger.debug("JTA TransactionSynchronizationRegistry found at default JNDI location [" + jndiName + "]");
}
@@ -742,14 +753,13 @@
}
}
// Check whether the UserTransaction or TransactionManager implements it...
- if (transactionSynchronizationRegistryClass.isInstance(ut)) {
- return ut;
+ if (ut instanceof TransactionSynchronizationRegistry) {
+ return (TransactionSynchronizationRegistry) ut;
}
- if (transactionSynchronizationRegistryClass.isInstance(tm)) {
- return tm;
+ if (tm instanceof TransactionSynchronizationRegistry) {
+ return (TransactionSynchronizationRegistry) tm;
}
- // OK, so no JTA 1.1 TransactionSynchronizationRegistry is available,
- // despite the API being present...
+ // OK, so no JTA 1.1 TransactionSynchronizationRegistry is available...
return null;
}
@@ -1136,7 +1146,7 @@
if (this.transactionSynchronizationRegistry != null) {
// JTA 1.1 TransactionSynchronizationRegistry available - use it.
- new InterposedSynchronizationDelegate().registerInterposedSynchronization(
+ this.transactionSynchronizationRegistry.registerInterposedSynchronization(
new JtaAfterCompletionSynchronization(synchronizations));
}
@@ -1163,6 +1173,7 @@
// Implementation of TransactionFactory interface
//---------------------------------------------------------------------
+ @Override
public Transaction createTransaction(String name, int timeout) throws NotSupportedException, SystemException {
TransactionManager tm = getTransactionManager();
Assert.state(tm != null, "No JTA TransactionManager available");
@@ -1173,6 +1184,7 @@
return new ManagedTransactionAdapter(tm);
}
+ @Override
public boolean supportsResourceAdapterManagedTransactions() {
return false;
}
@@ -1194,16 +1206,4 @@
initTransactionSynchronizationRegistry();
}
-
- /**
- * Inner class to avoid a direct dependency on the JTA 1.1 API
- * (javax.transaction.TransactionSynchronizationRegistry interface).
- */
- private class InterposedSynchronizationDelegate {
-
- public void registerInterposedSynchronization(Synchronization synch) {
- ((TransactionSynchronizationRegistry) transactionSynchronizationRegistry).registerInterposedSynchronization(synch);
- }
- }
-
}