--- C:\devel\grails-1.3.6\src\java\org\codehaus\groovy\grails\plugins\orm\hibernate\HibernatePluginSupport.groovy 2010-12-15 08:18:10.000000000 -0200 +++ C:\projects\grails-quick-patch\src\groovy\org\codehaus\groovy\grails\plugins\orm\hibernate\HibernatePluginSupport.groovy 2011-03-18 17:22:27.487700600 -0300 @@ -17,8 +17,10 @@ import grails.orm.HibernateCriteriaBuilder import grails.util.GrailsUtil +import grails.util.GrailsNameUtils import java.util.concurrent.ConcurrentHashMap +import java.lang.reflect.Modifier import org.apache.commons.beanutils.PropertyUtils import org.apache.commons.logging.Log @@ -70,6 +72,7 @@ import org.springframework.dao.DataAccessException import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor import org.springframework.orm.hibernate3.* +import org.springframework.transaction.TransactionDefinition import org.springframework.transaction.support.TransactionCallback import org.springframework.transaction.support.TransactionSynchronizationManager import org.springframework.transaction.support.TransactionTemplate @@ -498,11 +501,78 @@ ClassLoader classLoader = application.classLoader - metaClass.static.withTransaction = {Closure callable -> - new TransactionTemplate(ctx.getBean('transactionManager')).execute({status -> - callable.call(status) - } as TransactionCallback) - } + def baseWithTransactionImpl = { + Map sharedVars, Map defaultProperties, Map properties = null, Closure callable -> + + /* To allow less verbose property value and name. */ + def propsMapping = [isolation: "isolationLevelName", propagation: "propagationBehaviorName"] + + // Optimization + synchronized(sharedVars) { + if (sharedVars.isEmpty()) { + /* Lazy init of shared variables. */ + for (propName in propsMapping.keySet()) { + sharedVars[propName + "Mapping"] = [:] + } + + def modifier = Modifier.FINAL | Modifier.STATIC | Modifier.PUBLIC + /* Build NAME -> CONSTANT NAME mappings. */ + for (field in TransactionDefinition.class.declaredFields) { + if ((field.modifiers & modifier) == modifier) { + def constant = field + for (propName in propsMapping.keySet()) { + if (constant.name.startsWith(TransactionTemplate["PREFIX_" + propName.toUpperCase()])) { + def key = constant.name.replace(TransactionTemplate["PREFIX_" + propName.toUpperCase()], "") + key = key.replace("_", "-").toLowerCase() + sharedVars[propName + "Mapping"][GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(key)] = constant.name + } + } + } + } + } + } + + def newProperties = null + if (properties) { + /* To allow property overriding of "special" properties, they should be processed + in a specific order and LinkedHashMap should be used. */ + newProperties = new LinkedHashMap() + newProperties.putAll(defaultProperties); newProperties.putAll(properties) + } else { + newProperties = defaultProperties + } + properties = newProperties + def template = new TransactionTemplate(ctx.getBean('transactionManager')) + for (property in properties.entrySet()) { + def name = null, value = null + if (propsMapping.containsKey(property.key)) { + name = propsMapping[property.key] + value = sharedVars[property.key + "Mapping"][property.value] + } else { + name = property.key + value = property.value + } + println "template[${name}]=${value}" + template[name] = value + } + + template.execute({status -> callable.call(status)} as TransactionCallback) + } + + def withTxDefaults = [propagation: 'required'] + def withNewTxDefaults = [propagation: 'requiresNew'] + + baseWithTransactionImpl = baseWithTransactionImpl.curry([:]) + def withTransactionImpl = {Map properties = null, Closure callable -> + baseWithTransactionImpl(withTxDefaults, properties, callable) + } + def withNewTransactionImpl = {Map properties = null, Closure callable -> + baseWithTransactionImpl(withNewTxDefaults, properties, callable) + } + + + metaClass.static.withTransaction = withTransactionImpl + metaClass.static.withNewTransaction = withNewTransactionImpl metaClass.static.withSession = { Closure callable -> new HibernateTemplate(sessionFactory).execute({ session -> callable(session)