This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 7.1.x-hibernate6 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 5b906c40a69b742d6fee2a03a4928492fbbcb06c Author: Walter Duque de Estrada <[email protected]> AuthorDate: Thu Oct 16 19:07:50 2025 -0500 spring-boot --- gradle/publish-root-config.gradle | 2 + grails-data-hibernate6/boot-plugin/build.gradle | 67 ++++++++++ .../HibernateGormAutoConfiguration.groovy | 136 +++++++++++++++++++++ .../compiler/GormCompilerAutoConfiguration.groovy | 52 ++++++++ ...g.grails.cli.compiler.CompilerAutoConfiguration | 1 + ...rk.boot.autoconfigure.AutoConfiguration.imports | 1 + .../HibernateGormAutoConfigurationSpec.groovy | 93 ++++++++++++++ .../reader/GroovyBeanDefinitionReaderSpec.groovy | 57 +++++++++ grails-data-test-report/build.gradle | 8 -- settings.gradle | 4 +- 10 files changed, 411 insertions(+), 10 deletions(-) diff --git a/gradle/publish-root-config.gradle b/gradle/publish-root-config.gradle index c7293cdcc7..40d0ff1da2 100644 --- a/gradle/publish-root-config.gradle +++ b/gradle/publish-root-config.gradle @@ -117,6 +117,8 @@ def publishedProjects = [ 'grails-data-hibernate6', 'grails-data-hibernate6-core', 'grails-data-hibernate6-dbmigration', + 'grails-data-hibernate6-spring-boot', + // mongodb 'grails-data-mongodb', 'grails-data-mongodb-bson', diff --git a/grails-data-hibernate6/boot-plugin/build.gradle b/grails-data-hibernate6/boot-plugin/build.gradle new file mode 100644 index 0000000000..c946e9fa76 --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/build.gradle @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * https://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. + */ + +plugins { + id 'groovy' + id 'java-library' + id 'org.apache.grails.buildsrc.publish' + id 'org.apache.grails.buildsrc.sbom' +} + +version = projectVersion +group = 'org.apache.grails' + +ext { + gormApiDocs = true + pomTitle = 'Grails GORM' + pomDescription = 'GORM - Grails Data Access Framework' + pomDevelopers = [ + 'graemerocher': 'Graeme Rocher', + 'jeffscottbrown': 'Jeff Brown', + 'burtbeckwith': 'Burt Beckwith', + 'puneetbehl': 'Puneet Behl', + ] +} + +dependencies { + // TODO: Clarify and clean up dependencies + implementation platform(project(':grails-bom')) + + compileOnly project(':grails-shell-cli'), { + exclude group:'org.apache.groovy', module:'groovy' + } + api "org.apache.groovy:groovy" + api "org.springframework.boot:spring-boot-autoconfigure" + api project(":grails-data-hibernate6-core") + + testImplementation project(':grails-shell-cli'), { + exclude group:'org.apache.groovy', module:'groovy' + } + testImplementation "org.spockframework:spock-core" + + testRuntimeOnly "org.apache.tomcat:tomcat-jdbc" + testRuntimeOnly "com.h2database:h2" +} + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/hibernate6-test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle') +} diff --git a/grails-data-hibernate6/boot-plugin/src/main/groovy/org/grails/datastore/gorm/boot/autoconfigure/HibernateGormAutoConfiguration.groovy b/grails-data-hibernate6/boot-plugin/src/main/groovy/org/grails/datastore/gorm/boot/autoconfigure/HibernateGormAutoConfiguration.groovy new file mode 100644 index 0000000000..7167a13d9b --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/src/main/groovy/org/grails/datastore/gorm/boot/autoconfigure/HibernateGormAutoConfiguration.groovy @@ -0,0 +1,136 @@ +/* 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 + * + * https://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 org.grails.datastore.gorm.boot.autoconfigure + +import java.beans.Introspector + +import javax.sql.DataSource + +import groovy.transform.CompileStatic + +import org.hibernate.SessionFactory + +import org.springframework.beans.BeansException +import org.springframework.beans.factory.BeanFactory +import org.springframework.beans.factory.BeanFactoryAware +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory +import org.springframework.boot.autoconfigure.AutoConfigurationPackages +import org.springframework.boot.autoconfigure.AutoConfigureAfter +import org.springframework.boot.autoconfigure.AutoConfigureBefore +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware +import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.transaction.PlatformTransactionManager + +import org.grails.datastore.gorm.events.ConfigurableApplicationContextEventPublisher +import org.grails.datastore.mapping.services.Service +import org.grails.orm.hibernate.HibernateDatastore +import org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration + +/** + * Auto configuration for GORM for Hibernate + * + * @author Graeme Rocher + * @since 1.0 + */ +@CompileStatic +@Configuration +@ConditionalOnClass(HibernateMappingContextConfiguration) +@ConditionalOnBean(DataSource) +@ConditionalOnMissingBean(type = 'grails.orm.bootstrap.HibernateDatastoreSpringInitializer') +@AutoConfigureAfter(DataSourceAutoConfiguration) +@AutoConfigureBefore([HibernateJpaAutoConfiguration]) +class HibernateGormAutoConfiguration implements ApplicationContextAware,BeanFactoryAware { + + BeanFactory beanFactory + + @Autowired(required = false) + DataSource dataSource + + ConfigurableApplicationContext applicationContext + + @Bean + HibernateDatastore hibernateDatastore() { + List<String> packageNames = AutoConfigurationPackages.get(this.beanFactory) + List<Package> packages = [] + for (name in packageNames) { + Package pkg = Package.getPackage(name) + if (pkg != null) { + packages.add(pkg) + } + } + + ConfigurableListableBeanFactory beanFactory = applicationContext.beanFactory + HibernateDatastore datastore + if (dataSource == null) { + datastore = new HibernateDatastore( + applicationContext.getEnvironment(), + new ConfigurableApplicationContextEventPublisher(applicationContext), + packages as Package[] + ) + beanFactory.registerSingleton('dataSource', datastore.getDataSource()) + } + else { + datastore = new HibernateDatastore( + dataSource, + applicationContext.getEnvironment(), + new ConfigurableApplicationContextEventPublisher(applicationContext), + packages as Package[] + ) + } + + for (Service service in datastore.getServices()) { + Class serviceClass = service.getClass() + grails.gorm.services.Service ann = serviceClass.getAnnotation(grails.gorm.services.Service) + String serviceName = ann?.name() + if (serviceName == null) { + serviceName = Introspector.decapitalize(serviceClass.simpleName) + } + if (!applicationContext.containsBean(serviceName)) { + applicationContext.beanFactory.registerSingleton( + serviceName, + service + ) + } + } + return datastore + } + + @Bean + SessionFactory sessionFactory() { + hibernateDatastore().getSessionFactory() + } + + @Bean + PlatformTransactionManager hibernateTransactionManager() { + hibernateDatastore().getTransactionManager() + } + + @Override + void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (!(applicationContext instanceof ConfigurableApplicationContext)) { + throw new IllegalArgumentException('Neo4jAutoConfiguration requires an instance of ConfigurableApplicationContext') + } + this.applicationContext = (ConfigurableApplicationContext) applicationContext + } +} diff --git a/grails-data-hibernate6/boot-plugin/src/main/groovy/org/grails/datastore/gorm/boot/compiler/GormCompilerAutoConfiguration.groovy b/grails-data-hibernate6/boot-plugin/src/main/groovy/org/grails/datastore/gorm/boot/compiler/GormCompilerAutoConfiguration.groovy new file mode 100644 index 0000000000..32d7f22be7 --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/src/main/groovy/org/grails/datastore/gorm/boot/compiler/GormCompilerAutoConfiguration.groovy @@ -0,0 +1,52 @@ +/* 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 + * + * https://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 org.grails.datastore.gorm.boot.compiler + +import groovy.transform.CompileStatic +import org.codehaus.groovy.ast.ClassNode +import org.codehaus.groovy.control.CompilationFailedException +import org.codehaus.groovy.control.customizers.ImportCustomizer + +import org.grails.cli.compiler.AstUtils +import org.grails.cli.compiler.CompilerAutoConfiguration +import org.grails.cli.compiler.DependencyCustomizer + +/** + * A compiler configuration that automatically adds the necessary imports + * + * @author Graeme Rocher + * @since 1.0 + * + */ +@CompileStatic +class GormCompilerAutoConfiguration extends CompilerAutoConfiguration { + + @Override + boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, 'grails.persistence.Entity', 'grails.gorm.annotation.Entity', 'Entity') + } + + @Override + void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { + dependencies.ifAnyMissingClasses('grails.persistence.Entity', 'grails.gorm.annotation.Entity') + .add('grails-data-hibernate5-core') + } + + @Override + void applyImports(ImportCustomizer imports) throws CompilationFailedException { + imports.addStarImports('grails.gorm', 'grails.gorm.annotation') + } +} diff --git a/grails-data-hibernate6/boot-plugin/src/main/resources/META-INF/services/org.grails.cli.compiler.CompilerAutoConfiguration b/grails-data-hibernate6/boot-plugin/src/main/resources/META-INF/services/org.grails.cli.compiler.CompilerAutoConfiguration new file mode 100644 index 0000000000..2e0f07984f --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/src/main/resources/META-INF/services/org.grails.cli.compiler.CompilerAutoConfiguration @@ -0,0 +1 @@ +org.grails.datastore.gorm.boot.compiler.GormCompilerAutoConfiguration \ No newline at end of file diff --git a/grails-data-hibernate6/boot-plugin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/grails-data-hibernate6/boot-plugin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000000..d93153f929 --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.grails.datastore.gorm.boot.autoconfigure.HibernateGormAutoConfiguration diff --git a/grails-data-hibernate6/boot-plugin/src/test/groovy/org/grails/datastore/gorm/boot/autoconfigure/HibernateGormAutoConfigurationSpec.groovy b/grails-data-hibernate6/boot-plugin/src/test/groovy/org/grails/datastore/gorm/boot/autoconfigure/HibernateGormAutoConfigurationSpec.groovy new file mode 100644 index 0000000000..00a80ef176 --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/src/test/groovy/org/grails/datastore/gorm/boot/autoconfigure/HibernateGormAutoConfigurationSpec.groovy @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * https://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 org.grails.datastore.gorm.boot.autoconfigure + +import grails.gorm.annotation.Entity +import org.springframework.beans.factory.support.DefaultListableBeanFactory +import org.springframework.boot.autoconfigure.AutoConfigurationPackages +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration +import org.springframework.context.annotation.AnnotationConfigApplicationContext +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import +import org.springframework.core.env.MapPropertySource +import org.springframework.jdbc.datasource.DriverManagerDataSource +import spock.lang.Ignore +import spock.lang.Specification + +/** + * Created by graemerocher on 06/02/14. + */ +class HibernateGormAutoConfigurationSpec extends Specification{ + + protected AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + void cleanup() { + context.close() + } + + void setup() { + + AutoConfigurationPackages.register(context, "org.grails.datastore.gorm.boot.autoconfigure") + this.context.getEnvironment().getPropertySources().addFirst(new MapPropertySource("foo", ['hibernate.hbm2ddl.auto':'create'])) + def beanFactory = this.context.defaultListableBeanFactory + beanFactory.registerSingleton("dataSource", new DriverManagerDataSource("jdbc:h2:mem:grailsDb1;LOCK_TIMEOUT=10000;DB_CLOSE_DELAY=-1", 'sa', '')) + this.context.register( TestConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + } + + void 'Test that GORM is correctly configured'() { + when:"The context is refreshed" + context.refresh() + + def result = Person.withTransaction { + Person.count() + } + + then:"GORM queries work" + result == 0 + + when:"The addTo* methods are called" + def p = new Person() + p.addToChildren(firstName:"Bob") + + then:"They work too" + p.children.size() == 1 + } + + @Configuration + @Import(HibernateGormAutoConfiguration) + static class TestConfiguration { + } + +} + + +@Entity +class Person { + String firstName + String lastName + Integer age = 18 + + Set children = [] + static hasMany = [children: Person] +} + + diff --git a/grails-data-hibernate6/boot-plugin/src/test/groovy/org/springframework/bean/reader/GroovyBeanDefinitionReaderSpec.groovy b/grails-data-hibernate6/boot-plugin/src/test/groovy/org/springframework/bean/reader/GroovyBeanDefinitionReaderSpec.groovy new file mode 100644 index 0000000000..b762b73698 --- /dev/null +++ b/grails-data-hibernate6/boot-plugin/src/test/groovy/org/springframework/bean/reader/GroovyBeanDefinitionReaderSpec.groovy @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * https://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 org.springframework.bean.reader + +import org.springframework.beans.factory.InitializingBean +import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader +import org.springframework.context.annotation.AnnotationConfigApplicationContext +import spock.lang.Specification + +/** + * Created by graemerocher on 06/02/14. + */ +class GroovyBeanDefinitionReaderSpec extends Specification{ + + protected AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + void setup() { + MyBean.blah = 'foo' + } + + void "Test singletons are pre-instantiated with beans added by GroovyBeanDefinitionReader"() { + when:"The groovy reader is used" + def beanReader= new GroovyBeanDefinitionReader(context) + beanReader.beans { + myBean(MyBean) + } + + context.refresh() + + then:"The bean is pre instantiated" + MyBean.blah == 'created' + } +} +class MyBean implements InitializingBean{ + static String blah = 'foo' + + @Override + void afterPropertiesSet() throws Exception { + blah = 'created' + } +} diff --git a/grails-data-test-report/build.gradle b/grails-data-test-report/build.gradle index 736c6ffd4e..c7df3e72a9 100644 --- a/grails-data-test-report/build.gradle +++ b/grails-data-test-report/build.gradle @@ -33,14 +33,6 @@ dependencies { testReportAggregation project(':grails-datastore-web') } -reporting { - reports { - testAggregateTestReport(AggregateTestReport) { - testSuiteName = 'test' - } - } -} - tasks.named('check') { dependsOn tasks.named('testAggregateTestReport', TestReport) } diff --git a/settings.gradle b/settings.gradle index 8a63520aed..358a8163c1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -279,8 +279,8 @@ findProject(':grails-data-hibernate6').projectDir = new File(settingsDir, 'grail include 'grails-data-hibernate6-dbmigration' findProject(':grails-data-hibernate6-dbmigration').projectDir = new File(settingsDir, 'grails-data-hibernate6/dbmigration') // -//include 'grails-data-hibernate6-spring-boot' -//findProject(':grails-data-hibernate6-spring-boot').projectDir = new File(settingsDir, 'grails-data-hibernate6/boot-plugin') +include 'grails-data-hibernate6-spring-boot' +findProject(':grails-data-hibernate6-spring-boot').projectDir = new File(settingsDir, 'grails-data-hibernate6/boot-plugin') //// functional tests - hibernate6 examples //include 'grails-test-examples-hibernate6-grails-hibernate'
