You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by as...@apache.org on 2026/10/08 22:55:13 UTC
(grails-website) branch asf-site-production updated: Updating apache/grails-website asf-site-production branch for GitHub Actions run:37855152956
This is an automated email from the ASF dual-hosted git repository.
asf-ci-deploy pushed a commit to branch asf-site-production
in repository https://gitbox.apache.org/repos/asf/grails-website.git
The following commit(s) were added to refs/heads/asf-site-production by this push:
new 1f1f233fb07d Updating apache/grails-website asf-site-production branch for GitHub Actions run:37855152956
1f1f233fb07d is described below
commit 1f1f233fb07dfc35831eb55878040067328d4451
Author: jamesfredley <ja...@users.noreply.github.com>
AuthorDate: Thu Oct 8 22:55:01 2026 +0000
Updating apache/grails-website asf-site-production branch for GitHub Actions run:37855152956
---
foundation/minutes.xml | 2 +-
foundation/minutes/20210321-tab.html | 10 +++---
foundation/minutes/20211217-tab.html | 10 +++---
foundation/minutes/20220323-tab.html | 10 +++---
foundation/minutes/20220711-tab.html | 10 +++---
foundation/minutes/20221128-tab.html | 10 +++---
foundation/minutes/index.html | 2 +-
guides/_redirects.json | 2 +-
.../8/guide/domainClasses.html | 11 +++---
.../8/guide/index.html | 11 +++---
guides/database-per-tenant/8/guide/index.html | 6 ++--
.../database-per-tenant/8/guide/writingTheApp.html | 6 ++--
.../8/guide/associationWidgets.html | 20 +++++++++--
.../8/guide/domainModel.html | 20 ++++++++---
.../8/guide/index.html | 40 +++++++++++++++++-----
.../8/guide/domainModel.html | 6 ++--
.../grails-transactional-events/8/guide/index.html | 6 ++--
rss.xml | 2 +-
18 files changed, 119 insertions(+), 65 deletions(-)
diff --git a/foundation/minutes.xml b/foundation/minutes.xml
index aa320ee36ee4..098124672970 100644
--- a/foundation/minutes.xml
+++ b/foundation/minutes.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Foundation | Grails Framework</title><link>https://grails.apache.org</link><description>A powerful Groovy-based web application framework for the JVM built on top of Spring Boot</description><pubDate>Thu, 08 Oct 2026 22:19:57 GMT</pubDate><item><title>Technology Advisory Board Meeting</title><link>https://grails.apache.org/foundation/minutes/20221128-tab.html< [...]
+<?xml version="1.0" encoding="UTF-8"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Foundation | Grails Framework</title><link>https://grails.apache.org</link><description>A powerful Groovy-based web application framework for the JVM built on top of Spring Boot</description><pubDate>Thu, 08 Oct 2026 22:46:18 GMT</pubDate><item><title>Technology Advisory Board Meeting</title><link>https://grails.apache.org/foundation/minutes/20221128-tab.html< [...]
<h3>Meeting Attendance:</h3>
<ul>
<li><strong>Puneet Behl</strong> - Grails Product Development Lead at Object Computing</li>
diff --git a/foundation/minutes/20210321-tab.html b/foundation/minutes/20210321-tab.html
index 5e00b3d6eeb2..09f01f5eb114 100644
--- a/foundation/minutes/20210321-tab.html
+++ b/foundation/minutes/20210321-tab.html
@@ -318,17 +318,17 @@ community events</p>
<h3>2022</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@53c3e6f8</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@2cb89f06</minutesLink>
<parseDate>Nov 28, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@a9463f</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@41c498ba</minutesLink>
<parseDate>Jul 07, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@776e8872</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@498f819a</minutesLink>
<parseDate>Mar 23, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
@@ -336,12 +336,12 @@ community events</p>
<h3>2021</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@2b820da2</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@6e6d8cf1</minutesLink>
<parseDate>Dec 17, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@3d93ef8b</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@1b05d411</minutesLink>
<parseDate>Mar 21, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
diff --git a/foundation/minutes/20211217-tab.html b/foundation/minutes/20211217-tab.html
index dbcc5ab80fda..1e347f1e1561 100644
--- a/foundation/minutes/20211217-tab.html
+++ b/foundation/minutes/20211217-tab.html
@@ -360,17 +360,17 @@
<h3>2022</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@53c3e6f8</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@2cb89f06</minutesLink>
<parseDate>Nov 28, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@a9463f</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@41c498ba</minutesLink>
<parseDate>Jul 07, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@776e8872</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@498f819a</minutesLink>
<parseDate>Mar 23, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
@@ -378,12 +378,12 @@
<h3>2021</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@2b820da2</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@6e6d8cf1</minutesLink>
<parseDate>Dec 17, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@3d93ef8b</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@1b05d411</minutesLink>
<parseDate>Mar 21, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
diff --git a/foundation/minutes/20220323-tab.html b/foundation/minutes/20220323-tab.html
index afd21fb9892d..d69b15775a0a 100644
--- a/foundation/minutes/20220323-tab.html
+++ b/foundation/minutes/20220323-tab.html
@@ -403,17 +403,17 @@
<h3>2022</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@53c3e6f8</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@2cb89f06</minutesLink>
<parseDate>Nov 28, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@a9463f</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@41c498ba</minutesLink>
<parseDate>Jul 07, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@776e8872</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@498f819a</minutesLink>
<parseDate>Mar 23, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
@@ -421,12 +421,12 @@
<h3>2021</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@2b820da2</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@6e6d8cf1</minutesLink>
<parseDate>Dec 17, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@3d93ef8b</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@1b05d411</minutesLink>
<parseDate>Mar 21, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
diff --git a/foundation/minutes/20220711-tab.html b/foundation/minutes/20220711-tab.html
index 37385d5b19b8..10a86b082dd6 100644
--- a/foundation/minutes/20220711-tab.html
+++ b/foundation/minutes/20220711-tab.html
@@ -311,17 +311,17 @@
<h3>2022</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@53c3e6f8</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@2cb89f06</minutesLink>
<parseDate>Nov 28, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@a9463f</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@41c498ba</minutesLink>
<parseDate>Jul 07, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@776e8872</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@498f819a</minutesLink>
<parseDate>Mar 23, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
@@ -329,12 +329,12 @@
<h3>2021</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@2b820da2</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@6e6d8cf1</minutesLink>
<parseDate>Dec 17, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@3d93ef8b</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@1b05d411</minutesLink>
<parseDate>Mar 21, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
diff --git a/foundation/minutes/20221128-tab.html b/foundation/minutes/20221128-tab.html
index 1130fd8e9757..230d80ff73f3 100644
--- a/foundation/minutes/20221128-tab.html
+++ b/foundation/minutes/20221128-tab.html
@@ -350,17 +350,17 @@
<h3>2022</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@53c3e6f8</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@2cb89f06</minutesLink>
<parseDate>Nov 28, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@a9463f</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@41c498ba</minutesLink>
<parseDate>Jul 07, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@776e8872</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@498f819a</minutesLink>
<parseDate>Mar 23, 2022</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
@@ -368,12 +368,12 @@
<h3>2021</h3>
<ul>
<li>
- <minutesLink>website.model.HtmlMinutes@2b820da2</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@6e6d8cf1</minutesLink>
<parseDate>Dec 17, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
<li>
- <minutesLink>website.model.HtmlMinutes@3d93ef8b</minutesLink>
+ <minutesLink>website.model.HtmlMinutes@1b05d411</minutesLink>
<parseDate>Mar 21, 2021</parseDate>
<a href='minutesLink'>MMM dd - Technology Advisory Board Meeting</a>
</li>
diff --git a/foundation/minutes/index.html b/foundation/minutes/index.html
index efa3f13d392a..4ca3cf681dc1 100644
--- a/foundation/minutes/index.html
+++ b/foundation/minutes/index.html
@@ -205,7 +205,7 @@
</div>
</div>
-<article><div class='header-bar chalices-bg'><div class='content'><h1><a href='https://grails.apache.org/foundation/index.html'>Foundation</a></h1></div></div><div class='clear content container'><h3 class='column-header'>Meeting Minutes Archive</h3><div class='light'><div class='padded' style='padding-top: 0;'><div class="three-columns"><div class='column'><article class='blog-card' style='margin-bottom: 0; background-image: url(https://grails.apache.org/images/grails-blog-index-6.png)' [...]
+<article><div class='header-bar chalices-bg'><div class='content'><h1><a href='https://grails.apache.org/foundation/index.html'>Foundation</a></h1></div></div><div class='clear content container'><h3 class='column-header'>Meeting Minutes Archive</h3><div class='light'><div class='padded' style='padding-top: 0;'><div class="three-columns"><div class='column'><article class='blog-card' style='margin-bottom: 0; background-image: url(https://grails.apache.org/images/grails-blog-index-6.png)' [...]
<footer>
<div class='content'>
<div class='apache-grails'>
diff --git a/guides/_redirects.json b/guides/_redirects.json
index db3f1fdcd0a7..c7af62f9d0a8 100644
--- a/guides/_redirects.json
+++ b/guides/_redirects.json
@@ -1,6 +1,6 @@
{
"version": 1,
- "generated": "2026-10-08T22:19:53.291066849Z",
+ "generated": "2026-10-08T22:46:08.717235869Z",
"from_base": "https://guides.grails.org",
"to_base": "https://grails.apache.org/guides",
"count": 1795,
diff --git a/guides/creating-your-first-grails-app/8/guide/domainClasses.html b/guides/creating-your-first-grails-app/8/guide/domainClasses.html
index 58dfc65fe4b6..dd93e2816cb9 100644
--- a/guides/creating-your-first-grails-app/8/guide/domainClasses.html
+++ b/guides/creating-your-first-grails-app/8/guide/domainClasses.html
@@ -126,7 +126,7 @@ function addJsClass() {
<span class="predefined-type">String</span> name
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
}
<span class="predefined-type">String</span> toString() {
@@ -150,7 +150,8 @@ function addJsClass() {
<span class="directive">static</span> belongsTo = [<span class="key">make</span>: Make]
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ make <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
<span class="predefined-type">String</span> toString() {
@@ -175,8 +176,10 @@ function addJsClass() {
Model model
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
- year <span class="key">min</span>: <span class="integer">1900</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ year <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1900</span>
+ make <span class="key">nullable</span>: <span class="predefined-constant">false</span>
+ model <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
<span class="comment">// H2 treats YEAR as a reserved word; quote/rename the physical column.</span>
diff --git a/guides/creating-your-first-grails-app/8/guide/index.html b/guides/creating-your-first-grails-app/8/guide/index.html
index 7f4c326f18d6..ef5c1c06ede7 100644
--- a/guides/creating-your-first-grails-app/8/guide/index.html
+++ b/guides/creating-your-first-grails-app/8/guide/index.html
@@ -401,7 +401,7 @@ unzip creating-your-first-grails-app.zip</code></pre>
<span class="predefined-type">String</span> name
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
}
<span class="predefined-type">String</span> toString() {
@@ -425,7 +425,8 @@ unzip creating-your-first-grails-app.zip</code></pre>
<span class="directive">static</span> belongsTo = [<span class="key">make</span>: Make]
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ make <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
<span class="predefined-type">String</span> toString() {
@@ -450,8 +451,10 @@ unzip creating-your-first-grails-app.zip</code></pre>
Model model
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
- year <span class="key">min</span>: <span class="integer">1900</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
+ year <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1900</span>
+ make <span class="key">nullable</span>: <span class="predefined-constant">false</span>
+ model <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
<span class="comment">// H2 treats YEAR as a reserved word; quote/rename the physical column.</span>
diff --git a/guides/database-per-tenant/8/guide/index.html b/guides/database-per-tenant/8/guide/index.html
index 5749f784cfa4..d4efff7b3ccd 100644
--- a/guides/database-per-tenant/8/guide/index.html
+++ b/guides/database-per-tenant/8/guide/index.html
@@ -558,7 +558,7 @@ If the default data source can also be considered a tenant then the value of <co
<span class="predefined-type">String</span> name
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>
}
}</code></pre>
</div>
@@ -598,8 +598,8 @@ If the default data source can also be considered a tenant then the value of <co
year <span class="key">column</span>: <span class="string"><span class="delimiter">'</span><span class="content">`year`</span><span class="delimiter">'</span></span>
}
<span class="directive">static</span> constraints = {
- model <span class="key">blank</span>: <span class="predefined-constant">false</span>
- year <span class="key">min</span>: <span class="integer">1980</span>
+ model <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>
+ year <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1980</span>
}
}</code></pre>
</div>
diff --git a/guides/database-per-tenant/8/guide/writingTheApp.html b/guides/database-per-tenant/8/guide/writingTheApp.html
index ee0e5a87f587..e17059855364 100644
--- a/guides/database-per-tenant/8/guide/writingTheApp.html
+++ b/guides/database-per-tenant/8/guide/writingTheApp.html
@@ -347,7 +347,7 @@ If the default data source can also be considered a tenant then the value of <co
<span class="predefined-type">String</span> name
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>
}
}</code></pre>
</div>
@@ -387,8 +387,8 @@ If the default data source can also be considered a tenant then the value of <co
year <span class="key">column</span>: <span class="string"><span class="delimiter">'</span><span class="content">`year`</span><span class="delimiter">'</span></span>
}
<span class="directive">static</span> constraints = {
- model <span class="key">blank</span>: <span class="predefined-constant">false</span>
- year <span class="key">min</span>: <span class="integer">1980</span>
+ model <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>
+ year <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1980</span>
}
}</code></pre>
</div>
diff --git a/guides/grails-fields-custom-widgets-and-wrappers/8/guide/associationWidgets.html b/guides/grails-fields-custom-widgets-and-wrappers/8/guide/associationWidgets.html
index 15f0da15ddce..dbba65efadba 100644
--- a/guides/grails-fields-custom-widgets-and-wrappers/8/guide/associationWidgets.html
+++ b/guides/grails-fields-custom-widgets-and-wrappers/8/guide/associationWidgets.html
@@ -305,8 +305,22 @@ function addJsClass() {
<span class="tag"><g:message</span> <span class="attribute-name">code</span>=<span class="string"><span class="delimiter">"</span><span class="content">${referencedClass.simpleName.toLowerCase()}.label</span><span class="delimiter">"</span></span>
<span class="attribute-name">default</span>=<span class="string"><span class="delimiter">"</span><span class="content">${referencedClass.simpleName}</span><span class="delimiter">"</span></span><span class="tag">/></span>
<span class="tag"></legend></span>
- <span class="tag"><f:with</span> <span class="attribute-name">bean</span>=<span class="string"><span class="delimiter">"</span><span class="content">${value ?: referencedClass.newInstance()}</span><span class="delimiter">"</span></span> <span class="attribute-name">prefix</span>=<span class="string"><span class="delimiter">"</span><span class="content">${prefix}${property}.</span><span class="delimiter">"</span></span><span class="tag">></span>
- <span class="tag"><f:all</span><span class="tag">/></span>
+ <span class="error"><</span>%-- Grails Fields 8 passes only bean, property, and prefix into f:all,
+ so required on f:all is ignored. Set it on each child field.
+ An optional association must not HTML-require a blank child. --%<span class="error">></span>
+ <span class="tag"><g:set</span> <span class="attribute-name">var</span>=<span class="string"><span class="delimiter">"</span><span class="content">childBean</span><span class="delimiter">"</span></span> <span class="attribute-name">value</span>=<span class="string"><span class="delimiter">"</span><span class="content">${value ?: referencedClass.newInstance()}</span><span class="delimiter">"</span></span><span class="tag">/></span>
+ <span class="tag"><g:set</span> <span class="attribute-name">var</span>=<span class="string"><span class="delimiter">"</span><span class="content">childEntity</span><span class="delimiter">"</span></span> <span class="attribute-name">value</span>=<span class="string"><span class="delimiter">"</span><span class="content">${grailsApplication.mappingContext.getPersistentEntity(referencedClass.name)}</span><span class="delimiter">"</span></span><span class="tag [...]
+ <span class="tag"><f:with</span> <span class="attribute-name">bean</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childBean}</span><span class="delimiter">"</span></span> <span class="attribute-name">prefix</span>=<span class="string"><span class="delimiter">"</span><span class="content">${prefix}${property}.</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><g:each</span> <span class="attribute-name">in</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childEntity.persistentProperties}</span><span class="delimiter">"</span></span> <span class="attribute-name">var</span>=<span class="string"><span class="delimiter">"</span><span class="content">childProp</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><g:if</span> <span class="attribute-name">test</span>=<span class="string"><span class="delimiter">"</span><span class="content">${!(childProp instanceof org.grails.datastore.mapping.model.types.Association) </span><span class="content">&</span><span class="content">&</span> <span class="content">!(childProp.name in ['id', 'version', 'dateCreated', 'lastUpdated'])}</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><g:if</span> <span class="attribute-name">test</span>=<span class="string"><span class="delimiter">"</span><span class="content">${required}</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><f:field</span> <span class="attribute-name">property</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childProp.name}</span><span class="delimiter">"</span></span><span class="tag">/></span>
+ <span class="tag"></g:if></span>
+ <span class="tag"><g:else></span>
+ <span class="tag"><f:field</span> <span class="attribute-name">property</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childProp.name}</span><span class="delimiter">"</span></span> <span class="attribute-name">required</span>=<span class="string"><span class="delimiter">"</span><span class="content">false</span><span class="delimiter">"</span></span><span class="tag">/></span>
+ <span class="tag"></g:else></span>
+ <span class="tag"></g:if></span>
+ <span class="tag"></g:each></span>
<span class="tag"></f:with></span>
<span class="tag"></fieldset></span>
<span class="tag"></g:if></span>
@@ -332,7 +346,7 @@ function addJsClass() {
<p><code>persistentProperty.bidirectional && persistentProperty.inverseSide?.owningSide</code> is <code>true</code> when the other side declares <code>belongsTo: ParentClass</code> (or its bidirectional equivalent). The owning side’s row is created and destroyed with the parent.</p>
</li>
<li>
-<p>When owned, the template uses <code><f:with bean="${value ?: referencedClass.newInstance()}" prefix="${prefix}${property}."></code> to recursively render <code><f:all></code> for the child. The <code>prefix</code> ensures the child’s input names are like <code>author.contactInfo.phone</code> so Grails data binding cascades into the child object.</p>
+<p>When owned, the template uses <code><f:with bean="${value ?: referencedClass.newInstance()}" prefix="${prefix}${property}."></code> and renders each non-association child property with <code><f:field></code>. The <code>prefix</code> ensures the child’s input names are like <code>author.contactInfo.phone</code> so Grails data binding cascades into the child object. Grails Fields 8 ignores <code>required</code> on <code><f:all></code>, so an optional association [...]
</li>
<li>
<p>When not owned, the template falls through to a <code><select></code> of existing rows, exactly like many-to-one.</p>
diff --git a/guides/grails-fields-custom-widgets-and-wrappers/8/guide/domainModel.html b/guides/grails-fields-custom-widgets-and-wrappers/8/guide/domainModel.html
index e86324b479f5..dab93da7e0e8 100644
--- a/guides/grails-fields-custom-widgets-and-wrappers/8/guide/domainModel.html
+++ b/guides/grails-fields-custom-widgets-and-wrappers/8/guide/domainModel.html
@@ -178,6 +178,14 @@ function addJsClass() {
contactInfo <span class="key">nullable</span>: <span class="predefined-constant">true</span>
}
+ <span class="keyword">def</span> <span class="function">beforeValidate</span>() {
+ <span class="comment">// The optional contact fieldset is always rendered. A blank submission</span>
+ <span class="comment">// binds a new ContactInfo, which would fail its own required fields.</span>
+ <span class="keyword">if</span> (contactInfo && !contactInfo.id && !contactInfo.phone && !contactInfo.mailingAddress) {
+ contactInfo = <span class="predefined-constant">null</span>
+ }
+ }
+
<span class="directive">static</span> mapping = {
sort <span class="key">name</span>: <span class="string"><span class="delimiter">'</span><span class="content">asc</span><span class="delimiter">'</span></span>
}
@@ -227,8 +235,9 @@ function addJsClass() {
<span class="directive">static</span> belongsTo = [<span class="key">author</span>: Author]
<span class="directive">static</span> constraints = {
- phone <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">32</span>
- mailingAddress <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">500</span>, <span class="key">widget</span>: <span class="string"><span class="delimiter">'</span><span class="content">textarea</span><span class="delimiter">'</span></span>
+ author <span class="key">nullable</span>: <span class="predefined-constant">false</span>
+ phone <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">32</span>
+ mailingAddress <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">500</span>, <span class="key">widget</span>: <span class="string"><span class="delimiter">'</span><span class="content">textarea</span><span class="delimiter">'</span></span>
}
<span class="predefined-type">String</span> toString() { <span class="string"><span class="delimiter">"</span><span class="content">Contact for </span><span class="inline"><span class="inline-delimiter">${</span>author?.name<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> }
@@ -278,10 +287,11 @@ function addJsClass() {
<span class="directive">static</span> constraints = {
title <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
isbn <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">matches</span>: <span class="regexp"><span class="delimiter">/</span><span class="content">^(?:</span><span class="char">\d</span><span class="content">{10}|</span><span class="char">\d</span><span class="content">{13}|</span><span class="char">\d</span><span class="content">{3}-</span><span class [...]
- genre <span class="key">inList</span>: [<span class="string"><span class="delimiter">'</span><span class="content">Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Non-Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Biography</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</ [...]
+ author <span class="key">nullable</span>: <span class="predefined-constant">false</span>
+ genre <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">inList</span>: [<span class="string"><span class="delimiter">'</span><span class="content">Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Non-Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Biography</span><span [...]
description <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">2000</span>, <span class="key">widget</span>: <span class="string"><span class="delimiter">'</span><span class="content">textarea</span><span class="delimiter">'</span></span>
publishedDate <span class="key">nullable</span>: <span class="predefined-constant">false</span>
- priceUSD <span class="key">min</span>: <span class="float">0.00</span>G, <span class="key">scale</span>: <span class="integer">2</span>
+ priceUSD <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="float">0.00</span>G, <span class="key">scale</span>: <span class="integer">2</span>
inStock <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
@@ -331,7 +341,7 @@ function addJsClass() {
<span class="directive">static</span> belongsTo = <span class="predefined-type">Book</span>
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">60</span>, <span class="key">unique</span>: <span class="predefined-constant">true</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">60</span>, <span class="key">unique</span>: <span class="predefined-constant">true</span>
}
<span class="directive">static</span> mapping = {
diff --git a/guides/grails-fields-custom-widgets-and-wrappers/8/guide/index.html b/guides/grails-fields-custom-widgets-and-wrappers/8/guide/index.html
index 0524b2a3603c..93c11351cf8e 100644
--- a/guides/grails-fields-custom-widgets-and-wrappers/8/guide/index.html
+++ b/guides/grails-fields-custom-widgets-and-wrappers/8/guide/index.html
@@ -572,6 +572,14 @@ cd grails-fields-custom-widgets-and-wrappers/complete
contactInfo <span class="key">nullable</span>: <span class="predefined-constant">true</span>
}
+ <span class="keyword">def</span> <span class="function">beforeValidate</span>() {
+ <span class="comment">// The optional contact fieldset is always rendered. A blank submission</span>
+ <span class="comment">// binds a new ContactInfo, which would fail its own required fields.</span>
+ <span class="keyword">if</span> (contactInfo && !contactInfo.id && !contactInfo.phone && !contactInfo.mailingAddress) {
+ contactInfo = <span class="predefined-constant">null</span>
+ }
+ }
+
<span class="directive">static</span> mapping = {
sort <span class="key">name</span>: <span class="string"><span class="delimiter">'</span><span class="content">asc</span><span class="delimiter">'</span></span>
}
@@ -621,8 +629,9 @@ cd grails-fields-custom-widgets-and-wrappers/complete
<span class="directive">static</span> belongsTo = [<span class="key">author</span>: Author]
<span class="directive">static</span> constraints = {
- phone <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">32</span>
- mailingAddress <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">500</span>, <span class="key">widget</span>: <span class="string"><span class="delimiter">'</span><span class="content">textarea</span><span class="delimiter">'</span></span>
+ author <span class="key">nullable</span>: <span class="predefined-constant">false</span>
+ phone <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">32</span>
+ mailingAddress <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">500</span>, <span class="key">widget</span>: <span class="string"><span class="delimiter">'</span><span class="content">textarea</span><span class="delimiter">'</span></span>
}
<span class="predefined-type">String</span> toString() { <span class="string"><span class="delimiter">"</span><span class="content">Contact for </span><span class="inline"><span class="inline-delimiter">${</span>author?.name<span class="inline-delimiter">}</span></span><span class="delimiter">"</span></span> }
@@ -672,10 +681,11 @@ cd grails-fields-custom-widgets-and-wrappers/complete
<span class="directive">static</span> constraints = {
title <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">255</span>
isbn <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">matches</span>: <span class="regexp"><span class="delimiter">/</span><span class="content">^(?:</span><span class="char">\d</span><span class="content">{10}|</span><span class="char">\d</span><span class="content">{13}|</span><span class="char">\d</span><span class="content">{3}-</span><span class [...]
- genre <span class="key">inList</span>: [<span class="string"><span class="delimiter">'</span><span class="content">Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Non-Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Biography</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</ [...]
+ author <span class="key">nullable</span>: <span class="predefined-constant">false</span>
+ genre <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">inList</span>: [<span class="string"><span class="delimiter">'</span><span class="content">Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Non-Fiction</span><span class="delimiter">'</span></span>, <span class="string"><span class="delimiter">'</span><span class="content">Biography</span><span [...]
description <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">2000</span>, <span class="key">widget</span>: <span class="string"><span class="delimiter">'</span><span class="content">textarea</span><span class="delimiter">'</span></span>
publishedDate <span class="key">nullable</span>: <span class="predefined-constant">false</span>
- priceUSD <span class="key">min</span>: <span class="float">0.00</span>G, <span class="key">scale</span>: <span class="integer">2</span>
+ priceUSD <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="float">0.00</span>G, <span class="key">scale</span>: <span class="integer">2</span>
inStock <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
@@ -725,7 +735,7 @@ cd grails-fields-custom-widgets-and-wrappers/complete
<span class="directive">static</span> belongsTo = <span class="predefined-type">Book</span>
<span class="directive">static</span> constraints = {
- name <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">60</span>, <span class="key">unique</span>: <span class="predefined-constant">true</span>
+ name <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">60</span>, <span class="key">unique</span>: <span class="predefined-constant">true</span>
}
<span class="directive">static</span> mapping = {
@@ -1872,8 +1882,22 @@ If you want to see exactly which path the plugin chose, set the log level on <co
<span class="tag"><g:message</span> <span class="attribute-name">code</span>=<span class="string"><span class="delimiter">"</span><span class="content">${referencedClass.simpleName.toLowerCase()}.label</span><span class="delimiter">"</span></span>
<span class="attribute-name">default</span>=<span class="string"><span class="delimiter">"</span><span class="content">${referencedClass.simpleName}</span><span class="delimiter">"</span></span><span class="tag">/></span>
<span class="tag"></legend></span>
- <span class="tag"><f:with</span> <span class="attribute-name">bean</span>=<span class="string"><span class="delimiter">"</span><span class="content">${value ?: referencedClass.newInstance()}</span><span class="delimiter">"</span></span> <span class="attribute-name">prefix</span>=<span class="string"><span class="delimiter">"</span><span class="content">${prefix}${property}.</span><span class="delimiter">"</span></span><span class="tag">></span>
- <span class="tag"><f:all</span><span class="tag">/></span>
+ <span class="error"><</span>%-- Grails Fields 8 passes only bean, property, and prefix into f:all,
+ so required on f:all is ignored. Set it on each child field.
+ An optional association must not HTML-require a blank child. --%<span class="error">></span>
+ <span class="tag"><g:set</span> <span class="attribute-name">var</span>=<span class="string"><span class="delimiter">"</span><span class="content">childBean</span><span class="delimiter">"</span></span> <span class="attribute-name">value</span>=<span class="string"><span class="delimiter">"</span><span class="content">${value ?: referencedClass.newInstance()}</span><span class="delimiter">"</span></span><span class="tag">/></span>
+ <span class="tag"><g:set</span> <span class="attribute-name">var</span>=<span class="string"><span class="delimiter">"</span><span class="content">childEntity</span><span class="delimiter">"</span></span> <span class="attribute-name">value</span>=<span class="string"><span class="delimiter">"</span><span class="content">${grailsApplication.mappingContext.getPersistentEntity(referencedClass.name)}</span><span class="delimiter">"</span></span><span class="tag [...]
+ <span class="tag"><f:with</span> <span class="attribute-name">bean</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childBean}</span><span class="delimiter">"</span></span> <span class="attribute-name">prefix</span>=<span class="string"><span class="delimiter">"</span><span class="content">${prefix}${property}.</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><g:each</span> <span class="attribute-name">in</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childEntity.persistentProperties}</span><span class="delimiter">"</span></span> <span class="attribute-name">var</span>=<span class="string"><span class="delimiter">"</span><span class="content">childProp</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><g:if</span> <span class="attribute-name">test</span>=<span class="string"><span class="delimiter">"</span><span class="content">${!(childProp instanceof org.grails.datastore.mapping.model.types.Association) </span><span class="content">&</span><span class="content">&</span> <span class="content">!(childProp.name in ['id', 'version', 'dateCreated', 'lastUpdated'])}</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><g:if</span> <span class="attribute-name">test</span>=<span class="string"><span class="delimiter">"</span><span class="content">${required}</span><span class="delimiter">"</span></span><span class="tag">></span>
+ <span class="tag"><f:field</span> <span class="attribute-name">property</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childProp.name}</span><span class="delimiter">"</span></span><span class="tag">/></span>
+ <span class="tag"></g:if></span>
+ <span class="tag"><g:else></span>
+ <span class="tag"><f:field</span> <span class="attribute-name">property</span>=<span class="string"><span class="delimiter">"</span><span class="content">${childProp.name}</span><span class="delimiter">"</span></span> <span class="attribute-name">required</span>=<span class="string"><span class="delimiter">"</span><span class="content">false</span><span class="delimiter">"</span></span><span class="tag">/></span>
+ <span class="tag"></g:else></span>
+ <span class="tag"></g:if></span>
+ <span class="tag"></g:each></span>
<span class="tag"></f:with></span>
<span class="tag"></fieldset></span>
<span class="tag"></g:if></span>
@@ -1899,7 +1923,7 @@ If you want to see exactly which path the plugin chose, set the log level on <co
<p><code>persistentProperty.bidirectional && persistentProperty.inverseSide?.owningSide</code> is <code>true</code> when the other side declares <code>belongsTo: ParentClass</code> (or its bidirectional equivalent). The owning side’s row is created and destroyed with the parent.</p>
</li>
<li>
-<p>When owned, the template uses <code><f:with bean="${value ?: referencedClass.newInstance()}" prefix="${prefix}${property}."></code> to recursively render <code><f:all></code> for the child. The <code>prefix</code> ensures the child’s input names are like <code>author.contactInfo.phone</code> so Grails data binding cascades into the child object.</p>
+<p>When owned, the template uses <code><f:with bean="${value ?: referencedClass.newInstance()}" prefix="${prefix}${property}."></code> and renders each non-association child property with <code><f:field></code>. The <code>prefix</code> ensures the child’s input names are like <code>author.contactInfo.phone</code> so Grails data binding cascades into the child object. Grails Fields 8 ignores <code>required</code> on <code><f:all></code>, so an optional association [...]
</li>
<li>
<p>When not owned, the template falls through to a <code><select></code> of existing rows, exactly like many-to-one.</p>
diff --git a/guides/grails-transactional-events/8/guide/domainModel.html b/guides/grails-transactional-events/8/guide/domainModel.html
index 5d47c4983eed..98a689220dc6 100644
--- a/guides/grails-transactional-events/8/guide/domainModel.html
+++ b/guides/grails-transactional-events/8/guide/domainModel.html
@@ -206,9 +206,9 @@ function addJsClass() {
<span class="directive">static</span> constraints = {
eventType <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">64</span>
- orderId <span class="key">min</span>: <span class="integer">1L</span>
- customerId <span class="key">min</span>: <span class="integer">1L</span>
- orderTotal <span class="key">min</span>: <span class="keyword">new</span> <span class="predefined-type">BigDecimal</span>(<span class="string"><span class="delimiter">'</span><span class="content">0.01</span><span class="delimiter">'</span></span>)
+ orderId <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1L</span>
+ customerId <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1L</span>
+ orderTotal <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="keyword">new</span> <span class="predefined-type">BigDecimal</span>(<span class="string"><span class="delimiter">'</span><span class="content">0.01</span><span class="delimiter">'</span></span>)
occurredAt <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
diff --git a/guides/grails-transactional-events/8/guide/index.html b/guides/grails-transactional-events/8/guide/index.html
index 88031b42578f..4bb9b9c14b8a 100644
--- a/guides/grails-transactional-events/8/guide/index.html
+++ b/guides/grails-transactional-events/8/guide/index.html
@@ -623,9 +623,9 @@ cd grails-transactional-events</code></pre>
<span class="directive">static</span> constraints = {
eventType <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">blank</span>: <span class="predefined-constant">false</span>, <span class="key">maxSize</span>: <span class="integer">64</span>
- orderId <span class="key">min</span>: <span class="integer">1L</span>
- customerId <span class="key">min</span>: <span class="integer">1L</span>
- orderTotal <span class="key">min</span>: <span class="keyword">new</span> <span class="predefined-type">BigDecimal</span>(<span class="string"><span class="delimiter">'</span><span class="content">0.01</span><span class="delimiter">'</span></span>)
+ orderId <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1L</span>
+ customerId <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="integer">1L</span>
+ orderTotal <span class="key">nullable</span>: <span class="predefined-constant">false</span>, <span class="key">min</span>: <span class="keyword">new</span> <span class="predefined-type">BigDecimal</span>(<span class="string"><span class="delimiter">'</span><span class="content">0.01</span><span class="delimiter">'</span></span>)
occurredAt <span class="key">nullable</span>: <span class="predefined-constant">false</span>
}
diff --git a/rss.xml b/rss.xml
index 69a5b45cc9c2..843b9aa18885 100644
--- a/rss.xml
+++ b/rss.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Blog | Grails Framework</title><link>https://grails.apache.org</link><description>A powerful Groovy-based web application framework for the JVM built on top of Spring Boot</description><pubDate>Thu, 08 Oct 2026 22:19:57 GMT</pubDate><item><title>Apache Grails [%version] - Release Announcement</title><link>https://grails.apache.org/blog/2026-10-08-introducing-g [...]
+<?xml version="1.0" encoding="UTF-8"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Blog | Grails Framework</title><link>https://grails.apache.org</link><description>A powerful Groovy-based web application framework for the JVM built on top of Spring Boot</description><pubDate>Thu, 08 Oct 2026 22:46:17 GMT</pubDate><item><title>Apache Grails [%version] - Release Announcement</title><link>https://grails.apache.org/blog/2026-10-08-introducing-g [...]
<p>The Apache Grails community is excited to announce the 8.0.0 release of the Apache Grails Framework!</p>
<p>Grails 8 is the first major release planned and delivered entirely as an Apache Top-Level Project. Since the 8.0.x branch opened in November 2025, more than 4,000 commits across 400 pull requests have landed through six milestones and two release candidates. Grails 8 moves the platform to Java 21, Apache Groovy 5, Spring Boot 4.1 and Spring Framework 7, adds a GORM implementation for Hibernate 7, publishes GORM for Neo4j again, and changes plugin registration, CLI packaging, and GSP c [...]
<p>The Grails documentation is in the best shape it has ever been in. At the Grails 8 launch, <a href="/guides/versions/8.html">22 Grails guides</a> have been updated to Grails 8.</p>