grails -t forge create-app --data=hibernate7 com.example.demo
1 Introduction
Version: 8.0.0-SNAPSHOT
1 Introduction
Many modern web frameworks in the Java space are more complicated than needed and don’t embrace the Don’t Repeat Yourself (DRY) principles.
Dynamic frameworks like Rails and Django helped pave the way to a more modern way of thinking about web applications. Grails builds on these concepts and dramatically reduces the complexity of building web applications on the Java platform. What makes it different, however, is that it does so by building on already established Java technologies like Spring and Hibernate.
Grails is a full stack framework and attempts to solve as many pieces of the web development puzzle through the core technology and its associated plugins. Included out the box are things like:
-
GORM - An easy-to-use Object Mapping library with support for SQL, MongoDB, Neo4j and more.
-
View technologies for rendering HTML as well as JSON
-
A controller layer built on Spring Boot
-
A plugin system featuring hundreds of plugins.
-
Flexible profiles to create Web applications, Rest applications, plugins and more.
-
An interactive command line environment and build system based on Gradle
-
An embedded Tomcat container which is configured for on the fly reloading
All of these are made easy to use through the power of the Groovy language and the extensive use of Domain Specific Languages (DSLs)
This documentation will take you through getting started with Grails and building web applications with the Grails framework.
In addition to this documentation, there are comprehensive guides that walk you through various aspects of the technology.
Finally, Grails is far more than just a web framework and is made up of various sub-projects. The following table summarizes some other key projects in the eco-system with links to documentation.
| Project | Description |
|---|---|
An Object Mapping implementation for SQL databases |
|
An Object Mapping implementation for the MongoDB Document Database |
|
An Object Mapping implementation for Neo4j Graph Database |
|
A View technology for rendering HTML and other markup on the server |
|
A View technology for rendering JSON on the server side |
|
Asynchronous programming abstraction with support for RxJava, GPars and more |
1.1 What's new in Grails 8?
This section covers all the new features introduced in Grails 8
Overview
Grails 8 is a major release that includes new features, improvements, and dependency upgrades. This release focuses on enhancing the developer experience, improving performance, and ensuring compatibility with the latest technologies.
For detailed information on how to upgrade to Grails 8, including major dependency changes, please see the Upgrading from Grails 7 to Grails 8 section. Notable new features are included below.
Platform Baseline
Grails 8 raises the standard build and runtime baseline to Java 21 and uses Gradle 9.6.0. The standard Grails BOM remains on Groovy 5.0.7 and Spock 2.4-groovy-5.0, while Micronaut-enabled Grails applications use Micronaut-specific BOM variants that align with Micronaut 5 and require JDK 25 or later.
Spring Boot 4.1 and Spring Framework 7
Grails 8 is built on Spring Boot 4.1.0 and Spring Framework 7.0.8. This brings the Spring Boot 4 modular artifact layout, Spring Framework 7 API removals, Jackson 3, Tomcat 11 and Jakarta Servlet 6.1, plus Spring Boot 4.1 dependency management for Spring Security 7.1, Spring Data 2026.0 and Micrometer 1.17.
The Grails 8 upgrade guide calls out the major application-impacting changes and links to the Spring Boot 4.0 migration guide, Spring Boot 4.1 release notes and Spring Framework 7.0 release notes.
Hibernate 7 Application Generation
Grails Forge can now generate applications configured for Grails Data with Hibernate 7.
The create-* commands also accept a new -d, --data option (the previous -g and --gorm flags remain supported as legacy aliases) with the values hibernate5, hibernate7, and mongodb; the legacy value hibernate is still accepted and selects Hibernate 5:
Applications generated for Hibernate 7 consume grails-hibernate7-bom — or grails-hibernate7-micronaut-bom when combined with the grails-micronaut feature — consistently across the application dependencies, the buildscript classpath, and buildSrc.
This avoids the dependency resolution conflicts that occur when an application generated for Hibernate 5 is manually switched to grails-data-hibernate7 while the default grails-bom remains on the build classpath.
The database-migration feature also selects the matching grails-data-hibernate7-dbmigration plugin automatically.
Plugin Beans Register Before Spring Boot Auto-Configuration
Grails 8 unifies and retimes the plugin lifecycle so that the beans a plugin contributes are registered before Spring Boot processes its auto-configurations.
A plugin bean now takes precedence over a Spring Boot default guarded by @ConditionalOnMissingBean — Boot backs off in favour of the plugin’s bean, with no need to override or remove it afterwards.
Plugins register beans through the new beanRegistrar() hook, which returns a Spring Framework BeanRegistrar. Because BeanRegistrar is a functional interface, a closure coerced with as BeanRegistrar is all that is required:
import org.springframework.beans.factory.BeanRegistrar
import org.springframework.beans.factory.BeanRegistry
import org.springframework.core.env.Environment
import grails.plugins.Plugin
class MyGrailsPlugin extends Plugin {
@Override
BeanRegistrar beanRegistrar() {
{ BeanRegistry registry, Environment environment ->
registry.registerBean('myService', MyServiceImpl)
} as BeanRegistrar
}
}
beanRegistrar() replaces the doWithSpring bean builder DSL, which is deprecated in Grails 8.
The DSL continues to work for now, but you are strongly urged to migrate.
See the upgrade guide for details.
GSP Tag Library Improvements
Grails 8 continues the move toward method-based TagLib handlers while preserving compatibility with existing closure-based tags.
Method-defined tags now bind named attributes more predictably, exclude inherited framework and Object methods from tag dispatch, and preserve real namespace property getters.
The Grails Gradle extension now defaults preserveParameterNames to true, so application Groovy compilation preserves method parameter names for features such as typed method TagLib arguments.
Tag library unit tests also clean up and rebuild TagLib metadata automatically between features.
Tests that use TagLibUnitTest no longer need to manage purgeTagLibMetaClass, and specs that mock additional tag libraries continue to work across feature methods.
Namespace-Aware Link Generation
Links, form actions, pagination links, sortable column links, redirects, chains, and includes now resolve the target controller namespace automatically when namespace is omitted.
In the normal case, where only one controller has the target name, controller and action are enough to generate the correct namespaced or non-namespaced URL.
If multiple controllers share the same name, specify namespace to choose one explicitly.
Use namespace="" in GSP markup, or namespace: null in Groovy code, to target a non-namespaced controller.
@GrailsCompileStatic on Controllers That Use Tag Libraries
Controllers annotated with @GrailsCompileStatic can now invoke tag library methods without compile-time errors.
Both calling patterns are supported out of the box:
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
class BookController {
def index() {
// Direct call in the default namespace
response.writer << link(controller: 'book', action: 'list')
// Namespaced call via a dispatcher property
response.writer << my.customTag(attr: 'value')
}
}
@GrailsCompileStatic recognises controllers and tag libraries by convention and marks tag dispatch points as permissible dynamic calls, while leaving the rest of the class fully type-checked.
Opt All Controllers, Services and Tag Libraries into GrailsCompileStatic
Static compilation can now be enabled for every controller, service and tag library in an application from the nested compileStatic block of the grails build configuration, without annotating each class:
grails {
compileStatic {
controllers = true
services = true
tagLibs = true
}
}
All three options are disabled by default and independent, or compileStatic { all = true } can be used as a shortcut to enable all of them. Any class that declares its own @CompileDynamic (or @GrailsCompileStatic/@CompileStatic/@GrailsTypeChecked/@TypeChecked) annotation keeps that setting, so the opt-in never overrides an explicit per-class choice. Tag libraries that still declare tags as closure fields (the deprecated form) are skipped automatically by the tagLibs opt-in — left dynamically compiled with a build warning — so define tags as methods to opt them in. See the GrailsCompileStatic section for details.
Test HTTP Client Form Requests
Integration tests that implement HttpClientSupport can now use httpPostForm(…) to send application/x-www-form-urlencoded
request bodies. The helper URL-encodes form fields using UTF-8, and repeated values in a Collection or array are encoded as
repeated keys in insertion order.
Latency Testing Support
The new grails-testing-support-latency module injects artificial latency into the application under test, so that
requests randomly take longer. Slower responses widen the window in which timing bugs occur, turning intermittently
flaky functional tests — assertions that race a navigation, missing waits, ordering assumptions — into deterministic
failures. The module is inert until grails.testing.latency.enabled is set to true, and the delay range, the
fraction of requests affected, and the url patterns are all configurable. See the
Functional Testing section for details.
GORM for MongoDB: TTL, Text, and Reconciled Indexes
GORM for MongoDB can now declare a TTL index directly in the mapping DSL.
Adding expireAfterSeconds to the indexAttributes of a single date-valued property creates a TTL index, and MongoDB
automatically removes each document once it reaches the configured age:
class LoginEvent {
Date dateCreated
static mapping = {
dateCreated index: true, indexAttributes: [expireAfterSeconds: 3600]
}
}
A single property can likewise declare a $text index — or another special type such as 2dsphere — through
indexAttributes: [type: 'text'].
When the options of an already-created index change between restarts, GORM now reconciles the difference instead of only
logging a conflict. A changed TTL is applied in place with MongoDB’s collMod command — no drop, no rebuild — while any
other option change is applied by declaring indexAttributes: [recreateOnConflict: true].
GORM for MongoDB and Spring Data MongoDB Interoperability
A new optional module, grails-data-mongodb-spring-data, lets an application use GORM for MongoDB and
Spring Data MongoDB — its MongoTemplate and repositories — side by
side over the same MongoClient, database and codecs, and, within a single @Transactional method, the same
MongoDB transaction. When the module and spring-data-mongodb are on the classpath of a Spring Boot application that
already has a GORM MongoDatastore, it auto-configures a MongoDatabaseFactory, a MongoTemplate and a primary
transactionManager over GORM’s existing connection — GORM keeps ownership of the client:
@Transactional
void transfer(MongoTemplate mongoTemplate) {
new Account(name: "from").save() // GORM
mongoTemplate.insert(new LedgerEntry(amount: 10)) // Spring Data
// both commit together, or neither is applied if an exception is thrown
}
The unified transaction shares GORM’s server-side ClientSession, so it requires GORM multi-document transactions to
be enabled (grails.mongodb.transactional = true). Spring Data repositories are enabled the usual way with
@EnableMongoRepositories, on a package separate from the GORM @Entity classes; only the connection, codecs and
session are shared, and the two object-mapping models stay separate. See the
Spring Data MongoDB Interoperability section of the GORM for MongoDB
guide for details.
1.1.1 Updated Dependencies
Grails 8.0.0-SNAPSHOT ships with the following foundational dependency versions:
-
Java 21 minimum baseline
-
Groovy 5.0.7
-
Spring Framework 7.0.8
-
Spring Boot 4.1.0
-
Gradle 9.6.0
-
Spock 2.4-groovy-5.0
See the Grails BOM dependency table for the complete managed dependency set, including the Hibernate and Micronaut BOM variants.