All Downloads are FREE. Search and download functionalities are using the official Maven repository.

grails.orm.bootstrap.HibernateDatastoreSpringInitializer.groovy Maven / Gradle / Ivy

The newest version!
/* Copyright (C) 2014 SpringSource
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package grails.orm.bootstrap

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.grails.datastore.gorm.bootstrap.AbstractDatastoreInitializer
import org.grails.datastore.gorm.jdbc.connections.CachedDataSourceConnectionSourceFactory
import org.grails.datastore.gorm.support.AbstractDatastorePersistenceContextInterceptor
import org.grails.datastore.mapping.config.DatastoreServiceMethodInvokingFactoryBean
import org.grails.datastore.mapping.core.connections.AbstractConnectionSources
import org.grails.datastore.mapping.core.connections.ConnectionSource
import org.grails.datastore.mapping.reflect.ClassUtils
import org.grails.orm.hibernate.HibernateDatastore
import org.grails.orm.hibernate.cfg.Settings
import org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory
import org.grails.orm.hibernate.proxy.HibernateProxyHandler
import org.grails.orm.hibernate.support.HibernateDatastoreConnectionSourcesRegistrar
import org.springframework.beans.factory.support.BeanDefinitionRegistry
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationEventPublisher
import org.springframework.context.support.GenericApplicationContext
import org.springframework.core.env.ConfigurableEnvironment
import org.springframework.core.env.PropertyResolver
import org.springframework.transaction.PlatformTransactionManager

import javax.sql.DataSource

/**
 * Class that handles the details of initializing GORM for Hibernate
 *
 * @author Graeme Rocher
 * @since 3.0
 */
@Slf4j
class HibernateDatastoreSpringInitializer extends AbstractDatastoreInitializer {
    public static final String SESSION_FACTORY_BEAN_NAME = "sessionFactory"
    public static final String DEFAULT_DATA_SOURCE_NAME = Settings.SETTING_DATASOURCE
    public static final String DATA_SOURCES = Settings.SETTING_DATASOURCES;
    public static final String TEST_DB_URL = "jdbc:h2:mem:grailsDb;LOCK_TIMEOUT=10000;DB_CLOSE_DELAY=-1"

    String defaultDataSourceBeanName = ConnectionSource.DEFAULT
    String defaultSessionFactoryBeanName = SESSION_FACTORY_BEAN_NAME
    Set dataSources = [defaultDataSourceBeanName] as Set
    boolean enableReload = false
    boolean grailsPlugin = false

    HibernateDatastoreSpringInitializer(PropertyResolver configuration, Collection persistentClasses) {
        super(configuration, persistentClasses)
        configureDataSources(configuration)
    }

    HibernateDatastoreSpringInitializer(PropertyResolver configuration, Class... persistentClasses) {
        super(configuration, persistentClasses)
        configureDataSources(configuration)
    }

    HibernateDatastoreSpringInitializer(PropertyResolver configuration, String... packages) {
        super(configuration, packages)
        configureDataSources(configuration)
    }

    HibernateDatastoreSpringInitializer(Map configuration, Class... persistentClasses) {
        super(configuration, persistentClasses)
        configureDataSources(this.configuration)
    }

    HibernateDatastoreSpringInitializer(Map configuration, Collection persistentClasses) {
        super(configuration, persistentClasses)
        configureDataSources(this.configuration)
    }


    @CompileStatic
    void configureDataSources(PropertyResolver config) {

        Set dataSourceNames = new HashSet()

        if(config == null) {
            dataSourceNames = [defaultDataSourceBeanName] as Set
        }
        else {
            Map dataSources = config.getProperty(DATA_SOURCES, Map.class, Collections.emptyMap())

            if (dataSources != null && !dataSources.isEmpty()) {
                dataSourceNames.addAll( AbstractConnectionSources.toValidConnectionSourceNames(dataSources) )
            }
            Map dataSource = (Map)config.getProperty(DEFAULT_DATA_SOURCE_NAME, Map.class, Collections.emptyMap())
            if (dataSource != null && !dataSource.isEmpty()) {
                dataSourceNames.add( ConnectionSource.DEFAULT )
            }
        }
        this.dataSources = dataSourceNames
    }

    @Override
    protected Class getPersistenceInterceptorClass() {
        getClass().classLoader.loadClass('org.grails.plugin.hibernate.support.HibernatePersistenceContextInterceptor')
    }

    /**
     * Configures an in-memory test data source, don't use in production
     */
    @Override
    ApplicationContext configure() {
        GenericApplicationContext applicationContext = createApplicationContext()
        configureForBeanDefinitionRegistry(applicationContext)
        applicationContext.refresh()
        return applicationContext
    }

    protected String getTestDbUrl() {
        TEST_DB_URL
    }

    @CompileStatic
    ApplicationContext configureForDataSource(DataSource dataSource) {
        GenericApplicationContext applicationContext = createApplicationContext()
        applicationContext.beanFactory.registerSingleton(DEFAULT_DATA_SOURCE_NAME, dataSource)
        configureForBeanDefinitionRegistry(applicationContext)
        applicationContext.refresh()
        return applicationContext
    }

    public Closure getBeanDefinitions(BeanDefinitionRegistry beanDefinitionRegistry) {
        ApplicationEventPublisher eventPublisher = super.findEventPublisher(beanDefinitionRegistry)
        Closure beanDefinitions = {
            def common = getCommonConfiguration(beanDefinitionRegistry, "hibernate")
            common.delegate = delegate
            common.call()

            // for unwrapping / inspecting proxies
            hibernateProxyHandler(HibernateProxyHandler)

            def config = this.configuration
            final boolean isGrailsPresent = isGrailsPresent()
            dataSourceConnectionSourceFactory(CachedDataSourceConnectionSourceFactory)
            hibernateConnectionSourceFactory(HibernateConnectionSourceFactory, persistentClasses as Class[]) { bean ->
                bean.autowire = true
                dataSourceConnectionSourceFactory = ref('dataSourceConnectionSourceFactory')
            }
            hibernateDatastore(HibernateDatastore, config, hibernateConnectionSourceFactory, eventPublisher) { bean->
                bean.primary = true
            }
            sessionFactory(hibernateDatastore:'getSessionFactory') { bean->
                bean.primary = true
            }
            transactionManager(hibernateDatastore:"getTransactionManager") { bean->
                bean.primary = true
            }
            autoTimestampEventListener(hibernateDatastore:"getAutoTimestampEventListener")
            getBeanDefinition("transactionManager").beanClass = PlatformTransactionManager
            hibernateDatastoreConnectionSourcesRegistrar(HibernateDatastoreConnectionSourcesRegistrar, dataSources)
            // domain model mapping context, used for configuration
            grailsDomainClassMappingContext(hibernateDatastore:"getMappingContext")

            loadDataServices(null)
                    .each {serviceName, serviceClass->
                        "$serviceName"(DatastoreServiceMethodInvokingFactoryBean, serviceClass) {
                            targetObject = ref("hibernateDatastore")
                            targetMethod = 'getService'
                            arguments = [serviceClass]
                        }
                    }

            if(isGrailsPresent) {
                if(ClassUtils.isPresent("org.grails.plugin.hibernate.support.AggregatePersistenceContextInterceptor")) {
                    ClassLoader cl = ClassUtils.getClassLoader()
                    persistenceInterceptor(cl.loadClass("org.grails.plugin.hibernate.support.AggregatePersistenceContextInterceptor"), ref("hibernateDatastore"))
                    proxyHandler(cl.loadClass("org.grails.datastore.gorm.proxy.ProxyHandlerAdapter"), ref('hibernateProxyHandler'))
                }


                boolean osivEnabled = config.getProperty("hibernate.osiv.enabled", Boolean, true)
                boolean isWebApplication = beanDefinitionRegistry?.containsBeanDefinition("dispatcherServlet") ||
                        beanDefinitionRegistry?.containsBeanDefinition("grailsControllerHelper")

                if (isWebApplication && osivEnabled && ClassUtils.isPresent("org.grails.plugin.hibernate.support.GrailsOpenSessionInViewInterceptor")) {
                    ClassLoader cl = ClassUtils.getClassLoader()
                    openSessionInViewInterceptor(cl.loadClass("org.grails.plugin.hibernate.support.GrailsOpenSessionInViewInterceptor")) {
                        hibernateDatastore = ref("hibernateDatastore")
                    }
                }
            }
        }
        return beanDefinitions
    }


    protected GenericApplicationContext createApplicationContext() {
        GenericApplicationContext applicationContext = new GenericApplicationContext()
        if (configuration instanceof ConfigurableEnvironment) {
            applicationContext.environment = (ConfigurableEnvironment) configuration
        }
        applicationContext
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy