jdaugherty opened a new pull request, #16468:
URL: https://github.com/apache/grails-core/pull/16468
### Problem
A domain class whose identifier is mapped to a generator that is not one of
the built-in `ValueGenerator` constants, such as a Hibernate generator class
name:
```groovy
static mapping = {
id generator: 'com.example.CustomIdGenerator'
}
```
cannot be mocked in a unit test on 8.0.x. Any `DataTest`, `DomainUnitTest`,
or controller unit test that mocks the class fails during setup with:
```
java.lang.IllegalArgumentException: No enum constant
org.grails.datastore.mapping.model.ValueGenerator.COM.EXAMPLE.CUSTOMIDGENERATOR
```
The application itself starts and runs correctly, because the Hibernate 5
and Hibernate 7 mapping factories resolve the generator name themselves. Only
datastores that use the default identity mapping in `MappingFactory` are
affected: the simple map datastore that backs `DataTest`, and MongoDB.
### Cause
c74f868890 replaced the lazily evaluated identity mapping with
`DefaultIdentityMapping`, and resolved the generator name through
`ValueGenerator.valueOf` while the mapping is built. On Grails 7 the lookup
only ran when something read `IdentityMapping.getGenerator()`, which nothing on
the simple map or Mongo path does, so these domain classes mocked without
error. On 8.0.x the lookup runs during entity registration and throws.
Neo4j had already worked around this with its own override of
`createDefaultIdentityMapping`.
### Fix
`MappingFactory.createDefaultIdentityMapping` resolves a built-in name
case-insensitively as before, and resolves any other name to
`ValueGenerator.CUSTOM`, leaving the name on the mapped form for the datastore
to interpret. That is what the Hibernate and Neo4j factories already did for
themselves. The Neo4j override is removed because the base behaviour now
matches it.
The unit-testing guide notes that a mocked domain class never runs such a
generator, so its behaviour must be verified against the real datastore.
### Tests
- `IdentityGeneratorMappingSpec` (grails-datastore-core): built-in names in
lower and mixed case, a generator class name, a datastore-specific strategy
name, and no generator, through the key-value and document mapping contexts.
- `SimpleMapIdentifierSpec`: a custom generator class name and `assigned`
persist and are retrieved through real sessions.
- `MongoMappingContextSpec`: a generator class name is retained without a
server.
- Without the fallback, these specs and the Neo4j `SnowflakeIdGeneratorSpec`
fail with the error above; the Hibernate 5 `HibernateMappingContextSpec` still
passes, confirming the Hibernate path was never affected.
--
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]