codeconsole opened a new pull request, #15721:
URL: https://github.com/apache/grails-core/pull/15721

   ## Summary
   
   Change GORM's default constraint so an **unconstrained persistent property 
is nullable** (optional) rather than required. Today Grails applies an implicit 
`nullable: false` to every persistent property and every `Validateable` 
command‑object field; this PR flips that default to `nullable: true`.
   
   Two‑line change:
   - `DefaultConstraintEvaluator` — domain‑class default → nullable
   - `Validateable.defaultNullable()` — command‑object default → nullable
   
   ## Why this should be the Grails 8 default
   
   **Grails is the only mainstream JVM data framework that is 
required‑by‑default.** Every comparable layer treats an unconstrained property 
as nullable and makes you opt *into* "required":
   
   | Framework | Default for an unconstrained reference property |
   |---|---|
   | JPA / Hibernate | nullable (`@Column(nullable=false)` / `@NotNull` to 
require) |
   | Spring Data JPA | nullable |
   | Spring Data MongoDB | nullable (schemaless) |
   | Micronaut Data | nullable (`@NonNull` / Kotlin non‑null type to require) |
   | Jakarta Bean Validation (JSR‑380) | nullable — *no constraint = valid*; 
`@NotNull` is the opt‑in |
   | **Grails / GORM (today)** | **required** (`nullable: true` to allow null) |
   
   The case for flipping it:
   
   1. **Principle of least surprise / ecosystem consistency.** Developers 
arriving from Spring Boot, Micronaut, JPA, or plain Bean Validation expect 
"nullable unless I say otherwise." Grails inverts that — one of the most common 
first‑week surprises ("why does saving fail when I didn't mark anything 
required?").
   2. **It contradicts the storage layer.** SQL columns are nullable by 
default; MongoDB is schemaless. Grails' validation default is *stricter than 
the database it maps to*, for no structural reason.
   3. **It inverts the JSR‑380 contract.** Bean Validation defines "absence of 
a constraint ⇒ the value is valid (including null)"; `@NotNull` is the explicit 
opt‑in. Grails' implicit `nullable:false` is a silent, framework‑specific 
reversal of the spec it otherwise embraces.
   4. **It breaks composition.** Fields contributed by traits, base classes, or 
shared modules — or simply a new field added to an existing domain — silently 
become **required**, surfacing only as a runtime `ValidationException` on the 
first save (often in an unrelated path, e.g. a BootStrap seed). Mixing in 
reusable field sets is exactly the modular design Grails 8 should encourage; 
required‑by‑default punishes it.
   5. **A major version is the right time.** Defaults that no longer match the 
ecosystem should be corrected at a major boundary. Grails 8 is that boundary.
   
   ## Backward compatibility
   
   Deliberate behavior change, with a **one‑line opt‑out** to restore the 
legacy behavior:
   
   ```groovy
   // grails-app/conf/application.groovy — restore required-by-default for 
domains
   grails.gorm.default.constraints = {
       '*'(nullable: false)
   }
   ```
   ```groovy
   // command objects
   static boolean defaultNullable() { false }
   ```
   
   The existing `grails.gorm.default.constraints` machinery already applies 
`'*'` constraints *before* the framework default and skips the default when one 
is set (`canApplyNullableConstraint`), so the opt‑out composes cleanly with 
per‑property overrides.
   
   ## Notes / scope
   
   - Intentionally a small, focused diff to surface the proposal. The 
framework's own test suite and docs assert required‑by‑default in many places 
and would need a sweep if accepted — happy to follow up, or to gate the new 
default behind an explicit `grails.gorm.default.nullable` flag (defaulting to 
`true`) if preferred.
   - Opening against `8.0.x` for discussion.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to