Permalink
Browse files

Don't initialize the transaction manager until a bean is found that i…

…mplements TransactionManagerAware. Fixes grails/gorm-hibernate5#7

The TransactionManagerAwarePostProcessor was causing early initialization of all of GORM which meant GORM classes could not using @Autowired to process dependencies. This fixes that by only initiasing the transaction manager if a bean is found that implements TransactionManagerAware. This will be late enough in the process that by then the autowire bean post processor will have been registered.
  • Loading branch information...
1 parent e3d398b commit 5efc26945d756d47ba0a619708c4c27cedd278bf @graemerocher graemerocher committed Oct 6, 2016
@@ -16,6 +16,7 @@
package grails.transaction;
import org.springframework.beans.factory.Aware;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
/**
@@ -29,5 +30,6 @@
*
* @param transactionManager The TransactionManager implementation
*/
+ @Autowired
void setTransactionManager(PlatformTransactionManager transactionManager);
}
@@ -38,6 +38,7 @@
private ConfigurableListableBeanFactory beanFactory;
private PlatformTransactionManager transactionManager;
private int order = Ordered.LOWEST_PRECEDENCE;
+ private boolean initialized = false;
/**
* Gets the platform transaction manager from the bean factory if
@@ -50,7 +51,6 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
"TransactionManagerPostProcessor requires a ConfigurableListableBeanFactory");
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
- initialize();
}
/**
@@ -64,28 +64,34 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
@Override
public boolean postProcessAfterInstantiation(Object bean, String name) throws BeansException {
if (bean instanceof TransactionManagerAware) {
- TransactionManagerAware tma = (TransactionManagerAware) bean;
- tma.setTransactionManager(transactionManager);
+ initialize();
+ if(transactionManager != null) {
+ TransactionManagerAware tma = (TransactionManagerAware) bean;
+ tma.setTransactionManager(transactionManager);
+ }
}
return true;
}
private void initialize() {
- if (beanFactory.containsBean(GrailsApplication.TRANSACTION_MANAGER_BEAN)) {
- transactionManager = beanFactory.getBean(GrailsApplication.TRANSACTION_MANAGER_BEAN, PlatformTransactionManager.class);
- } else {
- // Fetch the names of all the beans that are of type
- // PlatformTransactionManager. Note that we have to pass
- // "false" for the last argument to avoid eager initialisation,
- // otherwise we end up in an endless loop (it triggers the current method).
- String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
- beanFactory, PlatformTransactionManager.class, false, false);
+ if(transactionManager == null && beanFactory != null && !initialized) {
+ if (beanFactory.containsBean(GrailsApplication.TRANSACTION_MANAGER_BEAN)) {
+ transactionManager = beanFactory.getBean(GrailsApplication.TRANSACTION_MANAGER_BEAN, PlatformTransactionManager.class);
+ } else {
+ // Fetch the names of all the beans that are of type
+ // PlatformTransactionManager. Note that we have to pass
+ // "false" for the last argument to avoid eager initialisation,
+ // otherwise we end up in an endless loop (it triggers the current method).
+ String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
+ beanFactory, PlatformTransactionManager.class, false, false);
- // If at least one is found, use the first of them as the
- // transaction manager for the application.
- if (beanNames.length > 0) {
- transactionManager = (PlatformTransactionManager)beanFactory.getBean(beanNames[0]);
+ // If at least one is found, use the first of them as the
+ // transaction manager for the application.
+ if (beanNames.length > 0) {
+ transactionManager = (PlatformTransactionManager)beanFactory.getBean(beanNames[0]);
+ }
}
+ initialized = true;
}
}
@@ -16,23 +16,16 @@
package org.grails.plugins.datasource
import grails.config.Config
-import grails.core.support.GrailsApplicationAware
+import grails.core.GrailsApplication
import grails.plugins.Plugin
import grails.util.Environment
import grails.util.GrailsUtil
-import grails.util.Metadata
-import org.springframework.context.ApplicationContext
-import org.springframework.context.ApplicationContextAware
-
-import javax.sql.DataSource
-
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.apache.tomcat.jdbc.pool.DataSource as TomcatDataSource
-import grails.core.GrailsApplication
import org.grails.core.exceptions.GrailsConfigurationException
-import org.grails.transaction.TransactionManagerPostProcessor
import org.grails.transaction.ChainedTransactionManagerPostProcessor
+import org.grails.transaction.TransactionManagerPostProcessor
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.jdbc.datasource.DriverManagerDataSource
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
@@ -41,6 +34,8 @@ import org.springframework.jmx.support.JmxUtils
import org.springframework.jndi.JndiObjectFactoryBean
import org.springframework.util.ClassUtils
+import javax.sql.DataSource
+
/**
* Handles the configuration of a DataSource within Grails.
*

0 comments on commit 5efc269

Please sign in to comment.