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

   A domain class that declares no `id` has always been given a `Long` one. 
That is right for Hibernate and wrong for MongoDB, where a `String id` holding 
a generated `ObjectId` needs no sequence collection and shards cleanly. 
Declaring `String id` gets that, but ties the source to MongoDB — the same 
class compiled against Hibernate would need `Long id` instead.
   
   This adds a build setting that lets each domain class take the identity type 
of the GORM implementation it is actually mapped with:
   
   ```groovy
   // build.gradle
   grails {
       gorm {
           defaultIdType = 'native'
       }
   }
   ```
   
   ```groovy
   // grails-app/domain/example/Person.groovy — names no store
   class Person {
       String name
   }
   ```
   
   Compiled with GORM for MongoDB, `Person` is given a `String id`. Compiled 
with Hibernate, it keeps `Long`. In an application using both, each domain 
class gets the right type from the single setting, resolved from its `mapWith` 
property. A domain class that declares an `id` keeps the type it declares.
   
   The default is `defaultIdType = 'long'`, which is the behaviour of every 
earlier release.
   
   ### How it resolves
   
   `GormEntityTransformation` already worked out which GORM implementation an 
entity belongs to, at compile time, in `pickGormEntityTrait` — from `mapWith` 
plus the `GormEntityTraitProvider`s on the compilation classpath. That 
resolution now also supplies the identity type, through a new default method on 
the SPI:
   
   ```groovy
   interface GormEntityTraitProvider {
       Class getEntityTrait()
       boolean isAvailable()
       default Class getDefaultIdentityType() { Long }
   }
   ```
   
   `MongoEntityTraitProvider` returns `String`. Hibernate and Neo4j inherit 
`Long`. Since the trait and the identity type now come from a single 
resolution, the two cannot disagree.
   
   The setting reaches the compiler as a system property published by the 
Gradle plugin, the same way `grails { compileStatic { } }` already does — a 
`CommandLineArgumentProvider` on 
`GroovyCompile.groovyOptions.forkOptions.jvmArgumentProviders`, with the 
effective value exposed as an `@Input` so that changing it invalidates the 
compile task. A stale class file would otherwise keep the type the previous 
setting asked for.
   
   `EntityASTTransformation` now runs the discovered domain injectors before 
`DefaultGrailsDomainClassInjector`. It ran that injector first, and it 
unconditionally adds a `Long` id, so GORM never got to decide the type on the 
`@grails.persistence.Entity` path. Each of the default injector's injections is 
guarded on the property not already being present, so it still fills in 
everything GORM did not.
   
   ### Limitations
   
   - The identity type is compiled into the class. The setting reaches the 
compiler through the Gradle plugin, so an IDE configured to compile without 
Gradle produces `Long` ids.
   - Turning this on changes the type of a column or field that already holds 
data. It is a setting to choose when an application is written, not one to 
switch on over an existing database.
   - A domain class compiled into a published plugin jar has its identity type 
fixed at plugin build time, not at consuming-application build time.
   - RX entities are unchanged and keep `Long`.
   - The scaffolding templates still hardcode `def show(Long id)` (and 
`edit`/`delete`). That is a pre-existing gap — it already affects the `String 
id` MongoDB domain classes the GORM for MongoDB guide recommends — and is left 
for a separate change.
   
   ### Documentation
   
   - `grails-data-mongodb` — new *Native Identity Types* section under 
*Identity Generation*
   - `grails-doc` — What's New in 8.0
   


-- 
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