You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/02/13 04:11:22 UTC
(grails-core) 10/21: standardized schema and catalog assignment
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 38a0436db516aba4b0488b200a2e4f9e6effebc4
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Wed Feb 11 10:41:18 2026 -0600
standardized schema and catalog assignment
---
.../orm/hibernate/cfg/GrailsDomainBinder.java | 47 ++++++++--------------
.../cfg/domainbinding/IdentityBinder.java | 37 ++++-------------
.../cfg/domainbinding/SimpleIdBinder.java | 28 +++++++++----
.../domainbinding/GrailsPropertyBinderSpec.groovy | 22 +++++-----
.../cfg/domainbinding/IdentityBinderSpec.groovy | 27 ++-----------
.../cfg/domainbinding/SimpleIdBinderSpec.groovy | 36 +++++++++++++----
6 files changed, 86 insertions(+), 111 deletions(-)
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
index 26209287af..a88c0b8695 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
@@ -16,7 +16,6 @@ package org.grails.orm.hibernate.cfg;
import groovy.lang.Closure;
-import org.grails.datastore.mapping.model.PersistentProperty;
import org.grails.datastore.mapping.model.config.GormProperties;
import org.grails.datastore.mapping.model.types.TenantId;
import org.grails.orm.hibernate.cfg.domainbinding.ClassBinder;
@@ -269,7 +268,7 @@ public class GrailsDomainBinder
Collections.emptyMap()
);
- Property property = collectionBinder.grailsDomainBinder.getProperty(persistentClass, tenantId.getName());
+ Property property = getProperty(persistentClass, tenantId.getName());
if (property.getValue() instanceof BasicValue basicValue) {
JdbcMapping jdbcMapping = basicValue.resolve().getJdbcMapping();
var stringVMap = Collections.singletonMap(GormProperties.TENANT_IDENTITY, jdbcMapping);
@@ -320,7 +319,7 @@ public class GrailsDomainBinder
subEntity.configureDerivedProperties();
if (!m.getTablePerHierarchy() && !m.isTablePerConcreteClass()) {
subClass = new JoinedSubclass(parent, this.metadataBuildingContext);
- bindJoinedSubClass(subEntity, (JoinedSubclass) subClass, mappings, m, sessionFactoryBeanName);
+ bindJoinedSubClass(subEntity, (JoinedSubclass) subClass, mappings, sessionFactoryBeanName);
}
else if(m.isTablePerConcreteClass()) {
subClass = new UnionSubclass(parent, this.metadataBuildingContext);
@@ -346,26 +345,15 @@ public class GrailsDomainBinder
@Nonnull InFlightMetadataCollector mappings, String sessionFactoryBeanName) throws MappingException {
classBinding.bindClass(subClass, unionSubclass, mappings);
- Mapping subMapping = subClass.getMappedForm();
-
- //TODO Verify if needed at all
-// if ( unionSubclass.getEntityPersisterClass() == null ) {
-// unionSubclass.getRootClass().setEntityPersisterClass(
-// UnionSubclassEntityPersister.class );
-// }
-
- String schema = subMapping != null && subMapping.getTable().getSchema() != null ?
- subMapping.getTable().getSchema() : null;
-
- String catalog = subMapping != null && subMapping.getTable().getCatalog() != null ?
- subMapping.getTable().getCatalog() : null;
+ String schema = subClass.getSchema(mappings);
+ String catalog = subClass.getCatalog(mappings);
Table denormalizedSuperTable = unionSubclass.getSuperclass().getTable();
Table mytable = mappings.addDenormalizedTable(
schema,
catalog,
new TableNameFetcher(getNamingStrategy()).getTableName(subClass),
- unionSubclass.isAbstract() != null && unionSubclass.isAbstract(),
+ Boolean.TRUE.equals(unionSubclass.isAbstract()),
null,
denormalizedSuperTable, metadataBuildingContext
);
@@ -383,22 +371,21 @@ public class GrailsDomainBinder
/**
* Binds a joined sub-class mapping using table-per-subclass
*
- * @param sub The Grails sub class
- * @param joinedSubclass The Hibernate Subclass object
- * @param mappings The mappings Object
- * @param gormMapping The GORM mapping object
- * @param sessionFactoryBeanName the session factory bean name
+ * @param sub The Grails sub class
+ * @param joinedSubclass The Hibernate Subclass object
+ * @param mappings The mappings Object
+ * @param sessionFactoryBeanName the session factory bean name
*/
private void bindJoinedSubClass(GrailsHibernatePersistentEntity sub, JoinedSubclass joinedSubclass,
- InFlightMetadataCollector mappings, Mapping gormMapping, String sessionFactoryBeanName) {
+ InFlightMetadataCollector mappings, String sessionFactoryBeanName) {
classBinding.bindClass(sub, joinedSubclass, mappings);
- String schemaName = NamespaceNameExtractor.getSchemaName(mappings);
- String catalogName = NamespaceNameExtractor.getCatalogName(mappings);
+ String schemaName = sub.getSchema(mappings);
+ String catalogName = sub.getCatalog(mappings);
Table mytable = mappings.addTable(
schemaName, catalogName,
- getJoinedSubClassTableName(sub, joinedSubclass, null, mappings, sessionFactoryBeanName),
+ getJoinedSubClassTableName(sub, joinedSubclass, null, mappings),
null, false, metadataBuildingContext);
joinedSubclass.setTable(mytable);
@@ -420,13 +407,13 @@ public class GrailsDomainBinder
private String getJoinedSubClassTableName(
GrailsHibernatePersistentEntity sub, PersistentClass model, Table denormalizedSuperTable,
- InFlightMetadataCollector mappings, String sessionFactoryBeanName) {
+ InFlightMetadataCollector mappings) {
String logicalTableName = GrailsHibernateUtil.unqualify(model.getEntityName());
String physicalTableName = new TableNameFetcher(getNamingStrategy()).getTableName(sub);
- String schemaName = NamespaceNameExtractor.getSchemaName(mappings);
- String catalogName = NamespaceNameExtractor.getCatalogName(mappings);
+ String schemaName = sub.getSchema(mappings);
+ String catalogName = sub.getCatalog(mappings);
mappings.addTableNameBinding(schemaName, catalogName, logicalTableName, physicalTableName, denormalizedSuperTable);
return physicalTableName;
@@ -637,7 +624,7 @@ public class GrailsDomainBinder
}
- public Property getProperty(PersistentClass associatedClass, String propertyName) throws MappingException {
+ private Property getProperty(PersistentClass associatedClass, String propertyName) throws MappingException {
try {
return associatedClass.getProperty(propertyName);
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinder.java
index 5c6e7dfb89..baec012d8e 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinder.java
@@ -9,6 +9,7 @@ import org.hibernate.mapping.RootClass;
import org.grails.datastore.mapping.model.PersistentProperty;
import org.grails.orm.hibernate.cfg.CompositeIdentity;
import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity;
+import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty;
import org.grails.orm.hibernate.cfg.HibernateIdentity;
import org.grails.orm.hibernate.cfg.Identity;
import org.grails.orm.hibernate.cfg.Mapping;
@@ -45,37 +46,15 @@ public class IdentityBinder {
Mapping gormMapping,
String sessionFactoryBeanName) {
- if (gormMapping != null) {
- HibernateIdentity id = gormMapping.getIdentity();
- if (id instanceof CompositeIdentity) {
- compositeIdBinder.bindCompositeId(domainClass, root, (CompositeIdentity) id, mappings, sessionFactoryBeanName);
- } else {
- final Identity identity = (Identity) id;
- PersistentProperty identifierProp = domainClass.getIdentity();
- String propertyName = identity.getName();
- if (propertyName != null && !propertyName.equals(domainClass.getName())) {
- PersistentProperty namedIdentityProp = domainClass.getPropertyByName(propertyName);
- if (namedIdentityProp == null) {
- throw new MappingException("Mapping specifies an identifier property name that doesn't exist [" + propertyName + "]");
- }
- if (!namedIdentityProp.equals(identifierProp)) {
- identifierProp = namedIdentityProp;
- }
- }
- if (identity.getName() == null) {
- identity.setName(root.getEntityName());
- }
- simpleIdBinder.bindSimpleId(identifierProp, root, identity);
- }
+ HibernateIdentity id = gormMapping != null ? gormMapping.getIdentity() : null;
+ if (id instanceof CompositeIdentity || (id == null && domainClass.getCompositeIdentity() != null)) {
+ compositeIdBinder.bindCompositeId(domainClass, root, (CompositeIdentity) id, mappings, sessionFactoryBeanName);
} else {
- if (domainClass.getCompositeIdentity() != null) {
- compositeIdBinder.bindCompositeId(domainClass, root, null, mappings, sessionFactoryBeanName);
- } else {
- PersistentProperty identifierProp = domainClass.getIdentity();
- if (identifierProp != null) {
- simpleIdBinder.bindSimpleId(identifierProp, root, null);
- }
+ Identity identity = id instanceof Identity ? (Identity) id : null;
+ if (identity != null && identity.getName() == null) {
+ identity.setName(root.getEntityName());
}
+ simpleIdBinder.bindSimpleId(domainClass, root, identity);
}
}
}
\ No newline at end of file
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinder.java
index 0c761eca73..5a89875a3c 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinder.java
@@ -8,6 +8,9 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.Table;
+import jakarta.annotation.Nonnull;
+import org.hibernate.MappingException;
+
import org.grails.datastore.mapping.model.PersistentProperty;
import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty;
import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity;
@@ -46,27 +49,36 @@ public class SimpleIdBinder {
}
- public void bindSimpleId(PersistentProperty identifier, RootClass entity, Identity mappedId) {
+ public void bindSimpleId(@Nonnull GrailsHibernatePersistentEntity domainClass, RootClass entity, Identity mappedId) {
- Mapping result = null;
- GrailsHibernatePersistentEntity domainClass = null;
- if (identifier.getOwner() instanceof GrailsHibernatePersistentEntity) {
- domainClass = (GrailsHibernatePersistentEntity) identifier.getOwner();
- result = domainClass.getMappedForm();
- }
+ Mapping result = domainClass.getMappedForm();
boolean useSequence = result != null && result.isTablePerConcreteClass();
// create the id value
BasicValueIdCreator idCreator = this.basicValueIdCreator != null ? this.basicValueIdCreator : new BasicValueIdCreator(metadataBuildingContext, jdbcEnvironment, domainClass, entity);
BasicValue id = idCreator.getBasicValueId(mappedId, useSequence);
+ var identifier = domainClass.getIdentity();
+ if (mappedId != null) {
+ String propertyName = mappedId.getName();
+ if (propertyName != null && !propertyName.equals(domainClass.getName())) {
+ var namedIdentityProp = (GrailsHibernatePersistentProperty) domainClass.getPropertyByName(propertyName);
+ if (namedIdentityProp == null) {
+ throw new MappingException("Mapping specifies an identifier property name that doesn't exist [" + propertyName + "]");
+ }
+ if (!namedIdentityProp.equals(identifier)) {
+ identifier = namedIdentityProp;
+ }
+ }
+ }
+
Property idProperty = new Property();
idProperty.setName(identifier.getName());
idProperty.setValue(id);
entity.setDeclaredIdentifierProperty(idProperty);
entity.setIdentifier(id);
// set type
- simpleValueBinder.bindSimpleValue((GrailsHibernatePersistentProperty) identifier, null, id, EMPTY_PATH);
+ simpleValueBinder.bindSimpleValue(identifier, null, id, EMPTY_PATH);
// create property
Property prop = new Property();
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
index 57005abbb9..ac75f72584 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
@@ -298,7 +298,11 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
def enumTypeBinder = Mock(EnumTypeBinder)
def componentPropertyBinder = Mock(ComponentPropertyBinder)
def collectionBinder = Mock(CollectionBinder)
- def propertyFromValueCreator = Mock(PropertyFromValueCreator) // Mock propertyFromValueCreator as it is a constructor parameter
+ def propertyFromValueCreator = Mock(PropertyFromValueCreator)
+ def simpleValueBinder = Mock(SimpleValueBinder)
+ def columnNameForPropertyAndPathFetcher = Mock(ColumnNameForPropertyAndPathFetcher)
+ def oneToOneBinder = Mock(OneToOneBinder)
+ def manyToOneBinder = Mock(ManyToOneBinder)
// Instantiate GrailsPropertyBinder using the protected constructor with necessary mocks
def propertyBinder = new GrailsPropertyBinder(
@@ -308,7 +312,10 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
enumTypeBinder,
componentPropertyBinder,
collectionBinder,
- propertyFromValueCreator
+ simpleValueBinder,
+ columnNameForPropertyAndPathFetcher,
+ oneToOneBinder,
+ manyToOneBinder
)
def mappings = Mock(org.hibernate.boot.spi.InFlightMetadataCollector)
@@ -330,17 +337,6 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
currentGrailsProp.getOwner() >> mockOwner
mockOwner.isRoot() >> true // Stub isRoot() to prevent NPE in ColumnBinder
- // Mock PropertyConfig and stub its methods for SimpleValueBinder
- def propertyConfigMock = Mock(PropertyConfig)
- currentGrailsProp.getMappedForm() >> propertyConfigMock // For SimpleValueBinder logic, need PropertyConfig
-
- propertyConfigMock.getGenerator() >> null
- propertyConfigMock.getTypeParams() >> new Properties()
- propertyConfigMock.isDerived() >> false
- def columnConfigMock = Mock(ColumnConfig) // Mock ColumnConfig for getColumns()
- columnConfigMock.getName() >> "test_column" // Provide a column name to prevent NPE
- propertyConfigMock.getColumns() >> Arrays.asList(columnConfigMock)
-
// Mocking other necessary properties of currentGrailsProp
currentGrailsProp.getType() >> String.class
currentGrailsProp.getName() >> "title"
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinderSpec.groovy
index a282a80533..61b2bda2d4 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IdentityBinderSpec.groovy
@@ -36,7 +36,7 @@ class IdentityBinderSpec extends HibernateGormDatastoreSpec {
binder.bindIdentity(domainClass, root, mappings, null, "sessionFactory")
then:
- 1 * simpleIdBinder.bindSimpleId(identifierProp, root, null)
+ 1 * simpleIdBinder.bindSimpleId(domainClass, root, null)
}
def "should delegate to compositeIdBinder when mapping is null and domainClass has composite identity"() {
@@ -87,25 +87,7 @@ class IdentityBinderSpec extends HibernateGormDatastoreSpec {
binder.bindIdentity(domainClass, root, mappings, gormMapping, "sessionFactory")
then:
- 1 * simpleIdBinder.bindSimpleId(identifierProp, root, identity)
- }
-
- def "should throw MappingException when mapping specifies a non-existent identifier property"() {
- given:
- def domainClass = Mock(GrailsHibernatePersistentEntity)
- def root = new RootClass(getGrailsDomainBinder().getMetadataBuildingContext())
- def mappings = Mock(InFlightMetadataCollector)
- def gormMapping = Mock(Mapping)
- def identity = new Identity(name: "nonExistent")
- gormMapping.getIdentity() >> identity
- domainClass.getName() >> "MyEntity"
- domainClass.getPropertyByName("nonExistent") >> null
-
- when:
- binder.bindIdentity(domainClass, root, mappings, gormMapping, "sessionFactory")
-
- then:
- thrown(org.hibernate.MappingException)
+ 1 * simpleIdBinder.bindSimpleId(domainClass, root, identity)
}
def "should not lookup property by name if identity name matches domain class name"() {
@@ -124,8 +106,7 @@ class IdentityBinderSpec extends HibernateGormDatastoreSpec {
binder.bindIdentity(domainClass, root, mappings, gormMapping, "sessionFactory")
then:
- 0 * domainClass.getPropertyByName(_)
- 1 * simpleIdBinder.bindSimpleId(identifierProp, root, identity)
+ 1 * simpleIdBinder.bindSimpleId(domainClass, root, identity)
}
def "should set entity name on identity if it is null"() {
@@ -146,6 +127,6 @@ class IdentityBinderSpec extends HibernateGormDatastoreSpec {
then:
identity.getName() == "MyEntity"
- 1 * simpleIdBinder.bindSimpleId(identifierProp, root, identity)
+ 1 * simpleIdBinder.bindSimpleId(domainClass, root, identity)
}
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinderSpec.groovy
index dfe5cf0d4b..87734e5ba5 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleIdBinderSpec.groovy
@@ -49,16 +49,18 @@ class SimpleIdBinderSpec extends HibernateGormDatastoreSpec {
}
def testProperty = Mock(GrailsHibernatePersistentProperty) {
getName() >> "id"
- getOwner() >> Mock(GrailsHibernatePersistentEntity) {
- getMappedForm() >> mapping
- }
+ }
+ def domainClass = Mock(GrailsHibernatePersistentEntity) {
+ getMappedForm() >> mapping
+ getIdentity() >> testProperty
+ getName() >> "TestEntity"
}
def rootClass = new RootClass(metadataBuildingContext)
currentTable = new Table("TEST_TABLE")
rootClass.setTable(currentTable)
when:
- simpleIdBinder.bindSimpleId(testProperty, rootClass, new Identity(generator: GrailsSequenceGeneratorEnum.IDENTITY.toString()))
+ simpleIdBinder.bindSimpleId(domainClass, rootClass, new Identity(generator: GrailsSequenceGeneratorEnum.IDENTITY.toString()))
then:
1 * simpleValueBinder.bindSimpleValue(testProperty as GrailsHibernatePersistentProperty, null, _, "")
@@ -77,16 +79,18 @@ class SimpleIdBinderSpec extends HibernateGormDatastoreSpec {
}
def testProperty = Mock(GrailsHibernatePersistentProperty) {
getName() >> "id"
- getOwner() >> Mock(GrailsHibernatePersistentEntity) {
- getMappedForm() >> mapping
- }
+ }
+ def domainClass = Mock(GrailsHibernatePersistentEntity) {
+ getMappedForm() >> mapping
+ getIdentity() >> testProperty
+ getName() >> "TestEntity"
}
def rootClass = new RootClass(metadataBuildingContext)
currentTable = new Table("TEST_TABLE")
rootClass.setTable(currentTable)
when:
- simpleIdBinder.bindSimpleId(testProperty, rootClass, new Identity(generator: GrailsSequenceGeneratorEnum.SEQUENCE.toString(), params: [sequence: 'SEQ_TEST']))
+ simpleIdBinder.bindSimpleId(domainClass, rootClass, new Identity(generator: GrailsSequenceGeneratorEnum.SEQUENCE.toString(), params: [sequence: 'SEQ_TEST']))
then:
1 * simpleValueBinder.bindSimpleValue(testProperty as GrailsHibernatePersistentProperty, null, _, "")
@@ -97,4 +101,20 @@ class SimpleIdBinderSpec extends HibernateGormDatastoreSpec {
rootClass.identifierProperty != null
rootClass.table.primaryKey instanceof PrimaryKey
}
+
+ def "bindSimpleId with non-existent identifier property"() {
+ given:
+ def domainClass = Mock(GrailsHibernatePersistentEntity) {
+ getName() >> "TestEntity"
+ getPropertyByName("nonExistent") >> null
+ getIdentity() >> Mock(GrailsHibernatePersistentProperty)
+ }
+ def rootClass = new RootClass(metadataBuildingContext)
+
+ when:
+ simpleIdBinder.bindSimpleId(domainClass, rootClass, new Identity(name: "nonExistent"))
+
+ then:
+ thrown(org.hibernate.MappingException)
+ }
}
\ No newline at end of file