This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch 8.0.x-hibernate7
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit 668a0af1c199aaa9f053e692b86e80ce33b0e67a
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Feb 21 22:33:38 2026 -0600

    refactor HibernateMappingFactory to standalone class
---
 .../orm/hibernate/cfg/HibernateMappingContext.java | 261 ++-------------------
 .../hibernate/HibernateMappingFactory.java         | 200 ++++++++++++++++
 .../gorm/specs/HibernateMappingFactorySpec.groovy  | 236 +++++++++++++++++++
 .../cfg/HibernateMappingContextSpec.groovy         |   4 +-
 4 files changed, 454 insertions(+), 247 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContext.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContext.java
index e8d86775e8..f23f9d443b 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContext.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContext.java
@@ -1,61 +1,32 @@
 /*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *    https://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
  *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
+ * Unless required by applicable law or agreed to in writing, * software 
distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT 
WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied.  See the 
License for the * specific language governing permissions and limitations * 
under the License.
  */
 package org.grails.orm.hibernate.cfg;
 
 import grails.gorm.hibernate.HibernateEntity;
 import groovy.lang.Closure;
-
-import java.beans.PropertyDescriptor;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
 import org.grails.datastore.gorm.GormEntity;
-import org.grails.datastore.mapping.config.AbstractGormMappingFactory;
-import org.grails.datastore.mapping.config.Property;
-import org.grails.datastore.mapping.config.groovy.MappingConfigurationBuilder;
-import org.grails.datastore.mapping.engine.types.CustomTypeMarshaller;
 import org.grails.datastore.mapping.model.*;
-import org.grails.datastore.mapping.reflect.ClassUtils;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsJpaMappingConfigurationStrategy;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateBasicProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateCustomProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedCollectionProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedPersistentEntity;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty;
-import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateIdentity;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateIdentityMapping;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateIdentityProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToManyProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToOneProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateMappingBuilder;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToManyProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToOneProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateSimpleProperty;
-import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateTenantIdProperty;
+import org.grails.orm.hibernate.cfg.domainbinding.hibernate.*;
 import org.grails.orm.hibernate.connections.HibernateConnectionSourceSettings;
 import org.grails.orm.hibernate.proxy.HibernateProxyHandler;
 
 /**
- * A Mapping context for Hibernate
+ * A Mapping context for Hibernate optimized for Java to Groovy conversion.
  *
  * @author Graeme Rocher
  * @since 5.0
@@ -65,22 +36,9 @@ public class HibernateMappingContext extends 
AbstractMappingContext {
   private final HibernateMappingFactory mappingFactory;
   private final MappingConfigurationStrategy syntaxStrategy;
 
-  /**
-   * Construct a HibernateMappingContext for the given arguments
-   *
-   * @param settings The {@link HibernateConnectionSourceSettings} settings
-   * @param contextObject The context object (for example a Spring 
ApplicationContext)
-   * @param persistentClasses The persistent classes
-   */
-  public HibernateMappingContext(
-      HibernateConnectionSourceSettings settings,
-      Object contextObject,
-      Class... persistentClasses) {
+  public HibernateMappingContext(HibernateConnectionSourceSettings settings, 
Object contextObject, Class... persistentClasses) {
     this.mappingFactory = new HibernateMappingFactory();
-
-    // The mapping factory needs to be configured before initialize can be 
safely called
     initialize(settings);
-
     if (settings != null) {
       
this.mappingFactory.setDefaultMapping(settings.getDefault().getMapping());
       
this.mappingFactory.setDefaultConstraints(settings.getDefault().getConstraints());
@@ -91,8 +49,7 @@ public class HibernateMappingContext extends 
AbstractMappingContext {
     addPersistentEntities(persistentClasses);
   }
 
-  public HibernateMappingContext(
-      HibernateConnectionSourceSettings settings, Class... persistentClasses) {
+  public HibernateMappingContext(HibernateConnectionSourceSettings settings, 
Class... persistentClasses) {
     this(settings, null, persistentClasses);
   }
 
@@ -100,11 +57,6 @@ public class HibernateMappingContext extends 
AbstractMappingContext {
     this(new HibernateConnectionSourceSettings());
   }
 
-  /**
-   * Sets the default constraints to be used
-   *
-   * @param defaultConstraints The default constraints
-   */
   public void setDefaultConstraints(Closure defaultConstraints) {
     this.mappingFactory.setDefaultConstraints(defaultConstraints);
   }
@@ -132,8 +84,7 @@ public class HibernateMappingContext extends 
AbstractMappingContext {
 
   @Override
   protected boolean isValidMappingStrategy(Class javaClass, Object 
mappingStrategy) {
-    return HibernateEntity.class.isAssignableFrom(javaClass)
-        || super.isValidMappingStrategy(javaClass, mappingStrategy);
+    return HibernateEntity.class.isAssignableFrom(javaClass) || 
super.isValidMappingStrategy(javaClass, mappingStrategy);
   }
 
   @Override
@@ -157,8 +108,7 @@ public class HibernateMappingContext extends 
AbstractMappingContext {
     return super.getPersistentEntity(name);
   }
 
-  public Collection<GrailsHibernatePersistentEntity> 
getHibernatePersistentEntities(
-      String dataSourceName) {
+  public Collection<GrailsHibernatePersistentEntity> 
getHibernatePersistentEntities(String dataSourceName) {
     List<GrailsHibernatePersistentEntity> result = new ArrayList<>();
     if (persistentEntities != null) {
       for (PersistentEntity entity : persistentEntities) {
@@ -170,183 +120,4 @@ public class HibernateMappingContext extends 
AbstractMappingContext {
     }
     return result;
   }
-
-  class HibernateMappingFactory extends AbstractGormMappingFactory<Mapping, 
PropertyConfig> {
-
-    public HibernateMappingFactory() {}
-
-    @Override
-    protected MappingConfigurationBuilder createConfigurationBuilder(
-        PersistentEntity entity, Mapping mapping) {
-      return new HibernateMappingBuilder(mapping, entity.getName(), 
defaultConstraints);
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.Identity<PropertyConfig> 
createIdentity(
-        PersistentEntity owner, MappingContext context, PropertyDescriptor pd) 
{
-      HibernateIdentityProperty identity = new 
HibernateIdentityProperty(owner, context, pd);
-      PropertyMapping<PropertyConfig> propertyMapping = 
createPropertyMapping(identity, owner);
-      identity.setMapping(propertyMapping);
-      return identity;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.TenantId<PropertyConfig> 
createTenantId(
-        PersistentEntity owner, MappingContext context, PropertyDescriptor pd) 
{
-      HibernateTenantIdProperty tenantId = new 
HibernateTenantIdProperty(owner, context, pd);
-      tenantId.setMapping(createDerivedPropertyMapping(tenantId, owner));
-      return tenantId;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.Custom<PropertyConfig> 
createCustom(
-        PersistentEntity owner, MappingContext context, PropertyDescriptor pd) 
{
-      final Class<?> propertyType = pd.getPropertyType();
-      CustomTypeMarshaller customTypeMarshaller = findCustomType(context, 
propertyType);
-      if (customTypeMarshaller == null && propertyType.isEnum()) {
-        customTypeMarshaller = findCustomType(context, Enum.class);
-      }
-      HibernateCustomProperty custom =
-          new HibernateCustomProperty(owner, context, pd, 
customTypeMarshaller);
-      custom.setMapping(createPropertyMapping(custom, owner));
-      return custom;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.Simple<PropertyConfig> 
createSimple(
-        PersistentEntity owner, MappingContext context, PropertyDescriptor pd) 
{
-      HibernateSimpleProperty simple = new HibernateSimpleProperty(owner, 
context, pd);
-      simple.setMapping(createPropertyMapping(simple, owner));
-      return simple;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.ToOne createOneToOne(
-        PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
-      HibernateOneToOneProperty oneToOne = new 
HibernateOneToOneProperty(entity, context, property);
-      oneToOne.setMapping(createPropertyMapping(oneToOne, entity));
-      return oneToOne;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.ToOne createManyToOne(
-        PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
-      HibernateManyToOneProperty manyToOne =
-          new HibernateManyToOneProperty(entity, context, property);
-      manyToOne.setMapping(createPropertyMapping(manyToOne, entity));
-      return manyToOne;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.OneToMany createOneToMany(
-        PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
-      HibernateOneToManyProperty oneToMany =
-          new HibernateOneToManyProperty(entity, context, property);
-      oneToMany.setMapping(createPropertyMapping(oneToMany, entity));
-      return oneToMany;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.ManyToMany 
createManyToMany(
-        PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
-      HibernateManyToManyProperty manyToMany =
-          new HibernateManyToManyProperty(entity, context, property);
-      manyToMany.setMapping(createPropertyMapping(manyToMany, entity));
-      return manyToMany;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.Embedded createEmbedded(
-        PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
-      HibernateEmbeddedProperty embedded = new 
HibernateEmbeddedProperty(entity, context, property);
-      embedded.setMapping(createPropertyMapping(embedded, entity));
-      return embedded;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.EmbeddedCollection 
createEmbeddedCollection(
-        PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
-      HibernateEmbeddedCollectionProperty embedded =
-          new HibernateEmbeddedCollectionProperty(entity, context, property);
-      embedded.setMapping(createPropertyMapping(embedded, entity));
-      return embedded;
-    }
-
-    @Override
-    public org.grails.datastore.mapping.model.types.Basic 
createBasicCollection(
-        PersistentEntity entity,
-        MappingContext context,
-        PropertyDescriptor property,
-        Class collectionType) {
-      HibernateBasicProperty basic =
-          new HibernateBasicProperty((GrailsHibernatePersistentEntity) entity, 
context, property);
-      basic.setMapping(createPropertyMapping(basic, entity));
-
-      CustomTypeMarshaller customTypeMarshaller =
-          findCustomType(context, property.getPropertyType());
-      if (collectionType != null && collectionType.isEnum()) {
-        customTypeMarshaller = findCustomType(context, collectionType);
-        if (customTypeMarshaller == null) {
-          customTypeMarshaller = findCustomType(context, Enum.class);
-        }
-      }
-
-      if (customTypeMarshaller != null) {
-        basic.setCustomTypeMarshaller(customTypeMarshaller);
-      }
-
-      return basic;
-    }
-
-    @Override
-    public IdentityMapping createIdentityMapping(final ClassMapping 
classMapping) {
-      final Mapping mappedForm = (Mapping) 
createMappedForm(classMapping.getEntity());
-      final HibernateIdentity identity = mappedForm.getIdentity();
-      final ValueGenerator generator;
-      if (identity instanceof Identity) {
-        Identity id = (Identity) identity;
-        String generatorName = id.getGenerator();
-        if (generatorName != null) {
-          ValueGenerator resolvedGenerator;
-          try {
-            resolvedGenerator =
-                
ValueGenerator.valueOf(generatorName.toUpperCase(java.util.Locale.ENGLISH));
-          } catch (IllegalArgumentException e) {
-            if (generatorName.equalsIgnoreCase("table")) {
-              resolvedGenerator = ValueGenerator.CUSTOM;
-            } else if (ClassUtils.isPresent(generatorName)) {
-              resolvedGenerator = ValueGenerator.CUSTOM;
-            } else {
-              throw new DatastoreConfigurationException(
-                  "Invalid id generation strategy for entity ["
-                      + classMapping.getEntity().getName()
-                      + "]: "
-                      + generatorName);
-            }
-          }
-          generator = resolvedGenerator;
-        } else {
-          generator = ValueGenerator.AUTO;
-        }
-      } else {
-        generator = ValueGenerator.AUTO;
-      }
-      return new HibernateIdentityMapping(identity, generator, classMapping);
-    }
-
-    @Override
-    protected boolean allowArbitraryCustomTypes() {
-      return true;
-    }
-
-    @Override
-    protected Class<PropertyConfig> getPropertyMappedFormType() {
-      return PropertyConfig.class;
-    }
-
-    @Override
-    protected Class<Mapping> getEntityMappedFormType() {
-      return Mapping.class;
-    }
-  }
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingFactory.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingFactory.java
new file mode 100644
index 0000000000..7df263a4ef
--- /dev/null
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingFactory.java
@@ -0,0 +1,200 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.grails.orm.hibernate.cfg.domainbinding.hibernate;
+
+import java.beans.PropertyDescriptor;
+import java.util.Locale;
+
+import org.grails.datastore.mapping.config.AbstractGormMappingFactory;
+import org.grails.datastore.mapping.config.groovy.MappingConfigurationBuilder;
+import org.grails.datastore.mapping.engine.types.CustomTypeMarshaller;
+import org.grails.datastore.mapping.model.*;
+import org.grails.datastore.mapping.model.types.*;
+import org.grails.datastore.mapping.reflect.ClassUtils;
+import org.grails.orm.hibernate.cfg.Identity;
+import org.grails.orm.hibernate.cfg.Mapping;
+import org.grails.orm.hibernate.cfg.PropertyConfig;
+
+/**
+ * The {@link AbstractGormMappingFactory} implementation for Hibernate, 
responsible for
+ * creating all Hibernate-specific persistent property and identity mapping 
instances.
+ */
+public class HibernateMappingFactory extends 
AbstractGormMappingFactory<Mapping, PropertyConfig> {
+
+  public HibernateMappingFactory() {
+  }
+
+  @Override
+  protected MappingConfigurationBuilder 
createConfigurationBuilder(PersistentEntity entity, Mapping mapping) {
+    return new HibernateMappingBuilder(mapping, entity.getName(), 
defaultConstraints);
+  }
+
+  @Override
+  public org.grails.datastore.mapping.model.types.Identity<PropertyConfig> 
createIdentity(
+      PersistentEntity owner, MappingContext context, PropertyDescriptor pd) {
+    HibernateIdentityProperty identity = new HibernateIdentityProperty(owner, 
context, pd);
+    identity.setMapping(createPropertyMapping(identity, owner));
+    return identity;
+  }
+
+  @Override
+  public TenantId<PropertyConfig> createTenantId(
+      PersistentEntity owner, MappingContext context, PropertyDescriptor pd) {
+    HibernateTenantIdProperty tenantId = new HibernateTenantIdProperty(owner, 
context, pd);
+    tenantId.setMapping(createDerivedPropertyMapping(tenantId, owner));
+    return tenantId;
+  }
+
+  @Override
+  public Custom<PropertyConfig> createCustom(
+      PersistentEntity owner, MappingContext context, PropertyDescriptor pd) {
+    final Class<?> propertyType = pd.getPropertyType();
+    CustomTypeMarshaller customTypeMarshaller = findCustomType(context, 
propertyType);
+    if (customTypeMarshaller == null && propertyType.isEnum()) {
+      customTypeMarshaller = findCustomType(context, Enum.class);
+    }
+    HibernateCustomProperty custom = new HibernateCustomProperty(owner, 
context, pd, customTypeMarshaller);
+    custom.setMapping(createPropertyMapping(custom, owner));
+    return custom;
+  }
+
+  @Override
+  public Simple<PropertyConfig> createSimple(
+      PersistentEntity owner, MappingContext context, PropertyDescriptor pd) {
+    HibernateSimpleProperty simple = new HibernateSimpleProperty(owner, 
context, pd);
+    simple.setMapping(createPropertyMapping(simple, owner));
+    return simple;
+  }
+
+  @Override
+  public ToOne createOneToOne(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
+    HibernateOneToOneProperty oneToOne = new HibernateOneToOneProperty(entity, 
context, property);
+    oneToOne.setMapping(createPropertyMapping(oneToOne, entity));
+    return oneToOne;
+  }
+
+  @Override
+  public ToOne createManyToOne(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
+    HibernateManyToOneProperty manyToOne = new 
HibernateManyToOneProperty(entity, context, property);
+    manyToOne.setMapping(createPropertyMapping(manyToOne, entity));
+    return manyToOne;
+  }
+
+  @Override
+  public OneToMany createOneToMany(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
+    HibernateOneToManyProperty oneToMany = new 
HibernateOneToManyProperty(entity, context, property);
+    oneToMany.setMapping(createPropertyMapping(oneToMany, entity));
+    return oneToMany;
+  }
+
+  @Override
+  public ManyToMany createManyToMany(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
+    HibernateManyToManyProperty manyToMany = new 
HibernateManyToManyProperty(entity, context, property);
+    manyToMany.setMapping(createPropertyMapping(manyToMany, entity));
+    return manyToMany;
+  }
+
+  @Override
+  public Embedded createEmbedded(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
+    HibernateEmbeddedProperty embedded = new HibernateEmbeddedProperty(entity, 
context, property);
+    embedded.setMapping(createPropertyMapping(embedded, entity));
+    return embedded;
+  }
+
+  @Override
+  public EmbeddedCollection createEmbeddedCollection(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property) {
+    HibernateEmbeddedCollectionProperty embedded =
+        new HibernateEmbeddedCollectionProperty(entity, context, property);
+    embedded.setMapping(createPropertyMapping(embedded, entity));
+    return embedded;
+  }
+
+  @Override
+  public Basic createBasicCollection(
+      PersistentEntity entity, MappingContext context, PropertyDescriptor 
property, Class collectionType) {
+    if (entity instanceof GrailsHibernatePersistentEntity ghpEntity) {
+      HibernateBasicProperty basic = new HibernateBasicProperty(ghpEntity, 
context, property);
+      basic.setMapping(createPropertyMapping(basic, entity));
+      CustomTypeMarshaller customTypeMarshaller = findCustomType(context, 
property.getPropertyType());
+      if (collectionType != null && collectionType.isEnum()) {
+        customTypeMarshaller = findCustomType(context, collectionType);
+        if (customTypeMarshaller == null) {
+          customTypeMarshaller = findCustomType(context, Enum.class);
+        }
+      }
+      if (customTypeMarshaller != null) {
+        basic.setCustomTypeMarshaller(customTypeMarshaller);
+      }
+      return basic;
+    }
+    return null;
+  }
+
+  @Override
+  public IdentityMapping createIdentityMapping(final ClassMapping 
classMapping) {
+    final Mapping mappedForm = (Mapping) 
createMappedForm(classMapping.getEntity());
+    final HibernateIdentity identity = mappedForm.getIdentity();
+    final ValueGenerator generator;
+
+    if (identity instanceof Identity id) {
+      String generatorName = id.getGenerator();
+      if (generatorName != null) {
+        ValueGenerator resolvedGenerator;
+        try {
+          resolvedGenerator = 
ValueGenerator.valueOf(generatorName.toUpperCase(Locale.ENGLISH));
+        } catch (IllegalArgumentException e) {
+          if (generatorName.equalsIgnoreCase("table") || 
ClassUtils.isPresent(generatorName)) {
+            resolvedGenerator = ValueGenerator.CUSTOM;
+          } else {
+            throw new DatastoreConfigurationException(
+                String.format("Invalid id generation strategy for entity [%s]: 
%s",
+                    classMapping.getEntity().getName(), generatorName));
+          }
+        }
+        generator = resolvedGenerator;
+      } else {
+        generator = ValueGenerator.AUTO;
+      }
+    } else {
+      generator = ValueGenerator.AUTO;
+    }
+    return new HibernateIdentityMapping(identity, generator, classMapping);
+  }
+
+  @Override
+  protected boolean allowArbitraryCustomTypes() {
+    return true;
+  }
+
+  @Override
+  protected Class<PropertyConfig> getPropertyMappedFormType() {
+    return PropertyConfig.class;
+  }
+
+  @Override
+  protected Class<Mapping> getEntityMappedFormType() {
+    return Mapping.class;
+  }
+}
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/specs/HibernateMappingFactorySpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/specs/HibernateMappingFactorySpec.groovy
new file mode 100644
index 0000000000..66863795a0
--- /dev/null
+++ 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/specs/HibernateMappingFactorySpec.groovy
@@ -0,0 +1,236 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package grails.gorm.specs
+
+import grails.gorm.annotation.Entity
+import grails.gorm.hibernate.HibernateEntity
+import grails.gorm.transactions.Rollback
+import 
org.grails.datastore.mapping.engine.types.AbstractMappingAwareCustomTypeMarshaller
+import org.grails.datastore.mapping.model.MappingContext
+import org.grails.datastore.mapping.model.PersistentEntity
+import org.grails.datastore.mapping.model.PersistentProperty
+import org.grails.datastore.mapping.model.ValueGenerator
+import org.grails.datastore.mapping.model.types.*
+import org.grails.orm.hibernate.cfg.HibernateMappingContext
+import org.grails.orm.hibernate.cfg.domainbinding.hibernate.*
+import org.grails.orm.hibernate.connections.HibernateConnectionSourceSettings
+
+/**
+ * Spec for {@link HibernateMappingFactory}, verifying that it creates
+ * the correct Hibernate-specific property and identity mapping instances.
+ */
+class HibernateMappingFactorySpec extends HibernateGormDatastoreSpec {
+
+    def setupSpec() {
+        manager.addAllDomainClasses([MappingFactoryBook, MappingFactoryAuthor, 
MappingFactoryTag,
+                                     MappingFactoryArticle])
+    }
+
+    // --- unit-style tests (standalone factory) ---
+
+    void "factory can be instantiated standalone"() {
+        when:
+        def factory = new HibernateMappingFactory()
+
+        then:
+        factory != null
+        factory.getPropertyMappedFormType() == 
org.grails.orm.hibernate.cfg.PropertyConfig
+        factory.getEntityMappedFormType() == 
org.grails.orm.hibernate.cfg.Mapping
+    }
+
+    void "allowArbitraryCustomTypes returns true"() {
+        expect:
+        new HibernateMappingFactory().allowArbitraryCustomTypes()
+    }
+
+    void "custom type marshaller is registered and detectable"() {
+        given:
+        HibernateConnectionSourceSettings settings = new 
HibernateConnectionSourceSettings()
+        settings.custom.types = [new FactoryTypeMarshaller(FactoryCustomType)]
+        def ctx = new HibernateMappingContext(settings)
+
+        expect:
+        ctx.mappingFactory.isCustomType(FactoryCustomType)
+    }
+
+    void "custom type marshaller is NOT registered for unrelated type"() {
+        given:
+        HibernateConnectionSourceSettings settings = new 
HibernateConnectionSourceSettings()
+        settings.custom.types = [new FactoryTypeMarshaller(FactoryCustomType)]
+        def ctx = new HibernateMappingContext(settings)
+
+        expect:
+        !ctx.mappingFactory.isCustomType(String)
+    }
+
+    // --- integration-style tests using live datastore ---
+
+    void "mappingFactory is a HibernateMappingFactory"() {
+        expect:
+        mappingContext.mappingFactory instanceof HibernateMappingFactory
+    }
+
+    void "createSimple produces HibernateSimpleProperty for a String field"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryBook.name)
+        def titleProp = entity.persistentProperties.find { it.name == 'title' }
+
+        then:
+        titleProp instanceof HibernateSimpleProperty
+    }
+
+    void "createManyToOne produces HibernateManyToOneProperty for a 
many-to-one association"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryBook.name)
+        def authorProp = entity.persistentProperties.find { it.name == 
'author' }
+
+        then:
+        authorProp instanceof HibernateManyToOneProperty
+    }
+
+    void "createOneToMany produces HibernateOneToManyProperty for a 
one-to-many association"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryAuthor.name)
+        def booksProp = entity.persistentProperties.find { it.name == 'books' }
+
+        then:
+        booksProp instanceof HibernateOneToManyProperty
+    }
+
+    void "createManyToMany produces HibernateManyToManyProperty"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryBook.name)
+        def tagsProp = entity.persistentProperties.find { it.name == 'tags' }
+
+        then:
+        tagsProp instanceof HibernateManyToManyProperty
+    }
+
+    void "createIdentity produces HibernateIdentityProperty"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryBook.name)
+
+        then:
+        entity.identity instanceof HibernateIdentityProperty
+    }
+
+    void "createIdentityMapping resolves NATIVE generator by default"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryBook.name)
+
+        then:
+        entity.mapping.identifier.generator == ValueGenerator.NATIVE
+    }
+
+    void "createIdentityMapping resolves CUSTOM generator for a custom class 
name"() {
+        when:
+        def ctx = new HibernateMappingContext()
+        PersistentEntity entity = 
ctx.addPersistentEntity(MappingFactoryCustomIdEntity)
+
+        then:
+        entity.mapping.identifier.generator == ValueGenerator.CUSTOM
+    }
+
+    void "createIdentityMapping returns HibernateIdentityMapping instance"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryBook.name)
+        def idMapping = entity.mapping.identifier
+
+        then:
+        idMapping instanceof HibernateIdentityMapping
+        idMapping.identifierName != null
+        idMapping.identifierName.length > 0
+    }
+
+    void "createEmbedded produces HibernateEmbeddedProperty"() {
+        when:
+        PersistentEntity entity = 
mappingContext.getPersistentEntity(MappingFactoryArticle.name)
+        def addrProp = entity.persistentProperties.find { it.name == 
'metadata' }
+
+        then:
+        addrProp instanceof HibernateEmbeddedProperty
+    }
+
+    @Rollback
+    void "factory-created entities can be persisted and retrieved"() {
+        when:
+        def author = new MappingFactoryAuthor(name: 'Test Author').save(flush: 
true)
+        def book = new MappingFactoryBook(title: 'Test Book', author: 
author).save(flush: true)
+
+        then:
+        MappingFactoryBook.count() >= 1
+        MappingFactoryBook.findByTitle('Test Book')?.author?.name == 'Test 
Author'
+    }
+}
+
+// --- domain classes ---
+
+@Entity
+class MappingFactoryAuthor implements HibernateEntity<MappingFactoryAuthor> {
+    String name
+    static hasMany = [books: MappingFactoryBook]
+}
+
+@Entity
+class MappingFactoryBook implements HibernateEntity<MappingFactoryBook> {
+    String title
+    MappingFactoryAuthor author
+    static belongsTo = [author: MappingFactoryAuthor]
+    static hasMany = [tags: MappingFactoryTag]
+}
+
+@Entity
+class MappingFactoryTag implements HibernateEntity<MappingFactoryTag> {
+    String name
+    static hasMany = [books: MappingFactoryBook]
+    static belongsTo = MappingFactoryBook
+}
+
+@Entity
+class MappingFactoryArticle implements HibernateEntity<MappingFactoryArticle> {
+    String title
+    MappingFactoryMetadata metadata
+    static embedded = ['metadata']
+}
+
+class MappingFactoryMetadata {
+    String description
+}
+
+@Entity
+class MappingFactoryCustomIdEntity implements 
HibernateEntity<MappingFactoryCustomIdEntity> {
+    String name
+    static mapping = {
+        id generator: 'grails.gorm.specs.FactoryCustomType', type: 
'uuid-binary'
+    }
+}
+
+// --- helpers ---
+
+class FactoryCustomType {}
+
+class FactoryTypeMarshaller extends AbstractMappingAwareCustomTypeMarshaller {
+    FactoryTypeMarshaller(Class targetType) { super(targetType) }
+
+    @Override
+    protected Object writeInternal(PersistentProperty property, String key, 
Object value, Object nativeTarget) { value }
+
+    @Override
+    protected Object readInternal(PersistentProperty property, String key, 
Object nativeSource) { nativeSource }
+}
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
index d5f78349f5..a102789dd1 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
@@ -161,10 +161,10 @@ class HibernateMappingContextSpec extends 
HibernateGormDatastoreSpec {
         entity.persistentProperties.find { it.name == "books" } != null
     }
 
-    void "getMappingFactory returns the HibernateMappingFactory"() {
+    void "getMappingFactory returns a HibernateMappingFactory"() {
         expect:
         mappingContext.mappingFactory != null
-        mappingContext.mappingFactory.class.simpleName == 
"HibernateMappingFactory"
+        mappingContext.mappingFactory instanceof 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateMappingFactory
     }
 }
 


Reply via email to