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 5c2248cfd1a95dd8fdb24c3f9b379f6b579547da Author: Walter B Duque de Estrada <[email protected]> AuthorDate: Sun Jan 25 20:26:33 2026 -0600 Heavy refactoring for cleaner implementation --- .../orm/hibernate/cfg/GrailsDomainBinder.java | 159 ++++++++++++++------- .../cfg/GrailsHibernatePersistentEntity.java | 19 +++ .../orm/hibernate/cfg/GrailsHibernateUtil.java | 2 +- .../cfg/HibernateEmbeddedPersistentEntity.java | 29 +++- .../orm/hibernate/cfg/HibernateMappingContext.java | 6 +- .../hibernate/cfg/HibernatePersistentEntity.java | 2 +- .../orm/hibernate/cfg/MappingCacheHolder.java | 50 +++++++ .../cfg/domainbinding/BasicValueIdCreator.java | 6 +- .../cfg/domainbinding/CascadeBehaviorFetcher.java | 7 +- .../hibernate/cfg/domainbinding/ColumnBinder.java | 9 +- .../cfg/domainbinding/EnumTypeBinder.java | 7 +- .../domainbinding/GrailsIncrementGenerator.java | 20 ++- .../cfg/domainbinding/ManyToOneBinder.java | 12 +- .../cfg/domainbinding/RootMappingFetcher.java | 8 +- .../cfg/domainbinding/SimpleIdBinder.java | 12 +- .../cfg/domainbinding/SimpleValueBinder.java | 12 +- .../cfg/domainbinding/TableNameFetcher.java | 10 +- .../hibernate/query/GrailsHibernateQueryUtils.java | 8 +- .../cfg/domainbinding/ColumnBinderSpec.groovy | 29 ++-- .../cfg/domainbinding/ManyToOneBinderSpec.groovy | 9 +- .../cfg/domainbinding/SimpleIdBinderSpec.groovy | 6 +- .../cfg/domainbinding/SimpleValueBinderSpec.groovy | 14 +- .../cfg/domainbinding/TableNameFetcherSpec.groovy | 3 +- .../mapping/model/AbstractMappingContext.java | 1 + 24 files changed, 314 insertions(+), 126 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 649a3d6389..055e54b103 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 @@ -109,13 +109,11 @@ import static org.hibernate.boot.model.naming.Identifier.toIdentifier; * @author Graeme Rocher * @since 0.1 */ -@SuppressWarnings("WeakerAccess") public class GrailsDomainBinder implements AdditionalMappingContributor, TypeContributor { public static final String FOREIGN_KEY_SUFFIX = "_id"; - protected static final Map<Class<?>, Mapping> MAPPING_CACHE = new HashMap<>(); private static final String STRING_TYPE = "string"; public static final String EMPTY_PATH = ""; public static final char UNDERSCORE = '_'; @@ -154,7 +152,7 @@ public class GrailsDomainBinder * @return A Mapping object or null */ public static Mapping getMapping(Class<?> theClass) { - return theClass == null ? null : MAPPING_CACHE.get(theClass); + return MappingCacheHolder.getInstance().getMapping(theClass); } /** @@ -173,7 +171,7 @@ public class GrailsDomainBinder * @param theClass The domain class in question */ public static void cacheMapping(Class<?> theClass, Mapping mapping) { - MAPPING_CACHE.put(theClass, mapping); + MappingCacheHolder.getInstance().cacheMapping(theClass, mapping); } /** @@ -184,25 +182,35 @@ public class GrailsDomainBinder */ public static Mapping getMapping(PersistentEntity domainClass) { if (domainClass == null) return null; + if (domainClass instanceof GrailsHibernatePersistentEntity) { + return getMapping((GrailsHibernatePersistentEntity) domainClass); + } org.grails.datastore.mapping.config.Entity mappedForm = domainClass.getMappedForm(); if (mappedForm instanceof Mapping) { return (Mapping) mappedForm; } - return MAPPING_CACHE.get(domainClass.getJavaClass()); + return MappingCacheHolder.getInstance().getMapping(domainClass.getJavaClass()); + } + + /** + * Obtains a mapping object for the given domain class nam + * + * @param domainClass The domain class in question + * @return A Mapping object or null + */ + public static Mapping getMapping(GrailsHibernatePersistentEntity domainClass) { + if (domainClass == null) return null; + return domainClass.getMappedForm(); } + + public static void clearMappingCache() { - MAPPING_CACHE.clear(); + MappingCacheHolder.getInstance().clear(); } public static void clearMappingCache(Class<?> theClass) { - String className = theClass.getName(); - for(Iterator<Map.Entry<Class<?>, Mapping>> it = MAPPING_CACHE.entrySet().iterator(); it.hasNext();) { - Map.Entry<Class<?>, Mapping> entry = it.next(); - if (className.equals(entry.getKey().getName())) { - it.remove(); - } - } + MappingCacheHolder.getInstance().clear(theClass); } @@ -218,8 +226,9 @@ public class GrailsDomainBinder this.dataSourceName = dataSourceName; this.hibernateMappingContext = hibernateMappingContext; this.classBinding = classBinding; + MappingCacheHolder.getInstance().clear(); // pre-build mappings - for (PersistentEntity persistentEntity : hibernateMappingContext.getPersistentEntities()) { + for (GrailsHibernatePersistentEntity persistentEntity : hibernateMappingContext.getHibernatePersistentEntities()) { evaluateMapping(persistentEntity); } } @@ -274,7 +283,7 @@ public class GrailsDomainBinder } - private boolean isForGrailsDomainMapping(HibernatePersistentEntity persistentEntity) { + private boolean isForGrailsDomainMapping(GrailsHibernatePersistentEntity persistentEntity) { return persistentEntity.forGrailsDomainMapping(dataSourceName); } @@ -330,7 +339,11 @@ public class GrailsDomainBinder SimpleValue elt = new BasicValue(metadataBuildingContext, map.getCollectionTable()); map.setElement(elt); - Mapping mapping = getMapping(property.getOwner()); + Mapping mapping = null; + GrailsHibernatePersistentEntity domainClass = (GrailsHibernatePersistentEntity) property.getOwner(); + if (domainClass != null) { + mapping = domainClass.getMappedForm(); + } String typeName = new TypeNameProvider().getTypeName(property, mapping); if (typeName == null ) { @@ -506,7 +519,7 @@ public class GrailsDomainBinder } } //NOTE: this will build the set for the in clause if it has sublcasses - Set<String> discSet = buildDiscriminatorSet((HibernatePersistentEntity) referenced); + Set<String> discSet = buildDiscriminatorSet((GrailsHibernatePersistentEntity) referenced); String inclause = String.join(",", discSet); collection.setWhere(discriminatorColumnName + " in (" + inclause + ")"); @@ -717,10 +730,10 @@ public class GrailsDomainBinder return false; } - private Set<String> buildDiscriminatorSet(HibernatePersistentEntity domainClass) { + private Set<String> buildDiscriminatorSet(GrailsHibernatePersistentEntity domainClass) { Set<String> theSet = new HashSet<>(); - Mapping mapping = domainClass.getMapping().getMappedForm(); + Mapping mapping = domainClass.getMappedForm(); String discriminator = domainClass.getName(); if (mapping != null && mapping.getDiscriminator() != null) { DiscriminatorConfig discriminatorConfig = mapping.getDiscriminator(); @@ -739,7 +752,7 @@ public class GrailsDomainBinder final java.util.Collection<PersistentEntity> childEntities = domainClass.getMappingContext().getDirectChildEntities(domainClass); for (PersistentEntity subClass : childEntities) { - theSet.addAll(buildDiscriminatorSet((HibernatePersistentEntity) subClass)); + theSet.addAll(buildDiscriminatorSet((GrailsHibernatePersistentEntity) subClass)); } return theSet; } @@ -782,7 +795,12 @@ public class GrailsDomainBinder } else { - Mapping mapping = getMapping(property.getOwner());; + Mapping mapping = null; + GrailsHibernatePersistentEntity domainClass = (GrailsHibernatePersistentEntity) property.getOwner(); + if (domainClass != null) { + mapping = domainClass.getMappedForm(); + } + ; String typeName = new TypeNameProvider().getTypeName(property, mapping); if (typeName == null) { Type type = mappings.getTypeConfiguration().getBasicTypeRegistry().getRegisteredType(className); @@ -806,7 +824,10 @@ public class GrailsDomainBinder } else { final PersistentEntity domainClass = property.getAssociatedEntity(); - Mapping m = getMapping(domainClass); + Mapping m = null; + if (domainClass != null) { + m = ((GrailsHibernatePersistentEntity) domainClass).getMappedForm(); + } if (m.hasCompositeIdentifier()) { CompositeIdentity ci = (CompositeIdentity) m.getIdentity(); new CompositeIdentifierToManyToOneBinder(namingStrategy).bindCompositeIdentifierToManyToOne(property, element, ci, domainClass, EMPTY_PATH); @@ -866,7 +887,10 @@ public class GrailsDomainBinder } PersistentEntity refDomainClass = property.getOwner(); - final Mapping mapping = getMapping(refDomainClass); + Mapping mapping = null; + if (refDomainClass != null) { + mapping = ((GrailsHibernatePersistentEntity) refDomainClass).getMappedForm(); + } boolean hasCompositeIdentifier = mapping.hasCompositeIdentifier(); if ((new ShouldCollectionBindWithJoinColumn().apply((ToMany) property) && hasCompositeIdentifier) || (hasCompositeIdentifier && ( property instanceof ManyToMany))) { @@ -1135,14 +1159,17 @@ public class GrailsDomainBinder throws MappingException { //if (domainClass.getClazz().getSuperclass() == Object.class) { if (entity.isRoot()) { - bindRoot((HibernatePersistentEntity) entity, mappings, sessionFactoryBeanName); + bindRoot((GrailsHibernatePersistentEntity) entity, mappings, sessionFactoryBeanName); } } - public void evaluateMapping(PersistentEntity persistentEntity) { + private void evaluateMapping(GrailsHibernatePersistentEntity persistentEntity) { Optional.ofNullable(persistentEntity).ifPresent(domainClass -> { try { - final Mapping m = getMapping(domainClass); + Mapping m = null; + if (domainClass != null) { + m = domainClass.getMappedForm(); + } for (PersistentProperty property : domainClass.getPersistentProperties()) { PropertyConfig propConf = m.getPropertyConfig(property.getName()); @@ -1150,7 +1177,8 @@ public class GrailsDomainBinder propConf.setExplicitSaveUpdateCascade(CascadeBehavior.isSaveUpdate(propConf.getCascade())); } } - cacheMapping(domainClass.getJavaClass(), m); + Class<?> theClass = domainClass.getJavaClass(); + MappingCacheHolder.getInstance().cacheMapping(theClass, m); } catch (Exception e) { throw new DatastoreConfigurationException("Error evaluating ORM mappings block for domain [" + domainClass.getName() + "]: " + e.getMessage(), e); @@ -1168,7 +1196,7 @@ public class GrailsDomainBinder * @param mappings The Hibernate Mappings object * @param sessionFactoryBeanName the session factory bean name */ - protected void bindRoot(HibernatePersistentEntity entity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { + protected void bindRoot(GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { if (mappings.getEntityBinding(entity.getName()) != null) { LOG.info("[GrailsDomainBinder] Class [" + entity.getName() + "] is already mapped, skipping.. "); return; @@ -1185,7 +1213,10 @@ public class GrailsDomainBinder root.setPolymorphic(false); } else { root.setPolymorphic(true); - Mapping m = getMapping(entity); + Mapping m = null; + if (entity != null) { + m = entity.getMappedForm(); + } boolean tablePerSubclass = !m.getTablePerHierarchy(); if (!tablePerSubclass) { // if the root class has children create a discriminator property @@ -1217,7 +1248,7 @@ public class GrailsDomainBinder * @param sessionFactoryBeanName the session factory bean name */ private void addMultiTenantFilterIfNecessary( - HibernatePersistentEntity entity, PersistentClass persistentClass, + GrailsHibernatePersistentEntity entity, PersistentClass persistentClass, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { if (entity.isMultiTenant()) { @@ -1258,20 +1289,20 @@ public class GrailsDomainBinder * @param sessionFactoryBeanName the session factory bean name * @param m */ - private void bindSubClasses(HibernatePersistentEntity domainClass, PersistentClass parent, + private void bindSubClasses(GrailsHibernatePersistentEntity domainClass, PersistentClass parent, InFlightMetadataCollector mappings, String sessionFactoryBeanName, Mapping m) { domainClass.getMappingContext() .getDirectChildEntities(domainClass) .stream() - .filter(HibernatePersistentEntity.class::isInstance) - .map(HibernatePersistentEntity.class::cast) + .filter(GrailsHibernatePersistentEntity.class::isInstance) + .map(GrailsHibernatePersistentEntity.class::cast) .filter(persistentEntity -> persistentEntity.usesConnectionSource(dataSourceName)) .filter(sub -> isChildEntity(sub, domainClass)) .forEach( sub -> bindSubClass(sub, parent, mappings, sessionFactoryBeanName, m)); } - private boolean isChildEntity(HibernatePersistentEntity sub, HibernatePersistentEntity parent) { + private boolean isChildEntity(GrailsHibernatePersistentEntity sub, GrailsHibernatePersistentEntity parent) { return sub.getJavaClass().getSuperclass().equals(parent.getJavaClass()); } @@ -1283,7 +1314,7 @@ public class GrailsDomainBinder * @param mappings The mappings instance * @param sessionFactoryBeanName the session factory bean name */ - private void bindSubClass(HibernatePersistentEntity sub, PersistentClass parent, + private void bindSubClass(GrailsHibernatePersistentEntity sub, PersistentClass parent, InFlightMetadataCollector mappings, String sessionFactoryBeanName,Mapping m) { evaluateMapping(sub); Subclass subClass; @@ -1301,7 +1332,10 @@ public class GrailsDomainBinder // set the descriminator value as the name of the class. This is the // value used by Hibernate to decide what the type of the class is // to perform polymorphic queries - Mapping subMapping = getMapping(sub); + Mapping subMapping = null; + if (sub != null) { + subMapping = sub.getMappedForm(); + } DiscriminatorConfig discriminatorConfig = subMapping.getDiscriminator(); subClass.setDiscriminatorValue(discriminatorConfig != null && discriminatorConfig.getValue() != null ? discriminatorConfig.getValue() : fullName); @@ -1349,11 +1383,14 @@ public class GrailsDomainBinder } - private void bindUnionSubclass(HibernatePersistentEntity subClass, UnionSubclass unionSubclass, + private void bindUnionSubclass(GrailsHibernatePersistentEntity subClass, UnionSubclass unionSubclass, InFlightMetadataCollector mappings, String sessionFactoryBeanName) throws MappingException { classBinding.bindClass(subClass, unionSubclass, mappings); - Mapping subMapping = getMapping(subClass); + Mapping subMapping = null; + if (subClass != null) { + subMapping = subClass.getMappedForm(); + } //TODO Verify if needed at all // if ( unionSubclass.getEntityPersisterClass() == null ) { @@ -1396,7 +1433,7 @@ public class GrailsDomainBinder * @param gormMapping The GORM mapping object * @param sessionFactoryBeanName the session factory bean name */ - private void bindJoinedSubClass(HibernatePersistentEntity sub, JoinedSubclass joinedSubclass, + private void bindJoinedSubClass(GrailsHibernatePersistentEntity sub, JoinedSubclass joinedSubclass, InFlightMetadataCollector mappings, Mapping gormMapping, String sessionFactoryBeanName) { classBinding.bindClass(sub, joinedSubclass, mappings); @@ -1426,7 +1463,7 @@ public class GrailsDomainBinder } private String getJoinedSubClassTableName( - HibernatePersistentEntity sub, PersistentClass model, Table denormalizedSuperTable, + GrailsHibernatePersistentEntity sub, PersistentClass model, Table denormalizedSuperTable, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { String logicalTableName = unqualify(model.getEntityName()); @@ -1446,7 +1483,7 @@ public class GrailsDomainBinder * @param subClass The Hibernate SubClass instance * @param mappings The mappings instance */ - private void bindSubClass(HibernatePersistentEntity sub, Subclass subClass, InFlightMetadataCollector mappings, + private void bindSubClass(GrailsHibernatePersistentEntity sub, Subclass subClass, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { classBinding.bindClass(sub, subClass, mappings); @@ -1518,11 +1555,14 @@ public class GrailsDomainBinder /* * Binds a persistent classes to the table representation and binds the class properties */ - private void bindRootPersistentClassCommonValues(HibernatePersistentEntity domainClass, + private void bindRootPersistentClassCommonValues(GrailsHibernatePersistentEntity domainClass, RootClass root, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { // get the schema and catalog names from the configuration - Mapping gormMapping = getMapping(domainClass); + Mapping gormMapping = null; + if (domainClass != null) { + gormMapping = domainClass.getMappedForm(); + } configureDerivedProperties(domainClass, gormMapping); CacheConfig cc = gormMapping.getCache(); @@ -1570,7 +1610,7 @@ public class GrailsDomainBinder private void bindIdentity( - HibernatePersistentEntity domainClass, + GrailsHibernatePersistentEntity domainClass, RootClass root, InFlightMetadataCollector mappings, Mapping gormMapping, @@ -1609,7 +1649,7 @@ public class GrailsDomainBinder private void bindCompositeId(PersistentEntity domainClass, RootClass root, CompositeIdentity compositeIdentity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { - HibernatePersistentEntity hibernatePersistentEntity = (HibernatePersistentEntity) domainClass; + GrailsHibernatePersistentEntity hibernatePersistentEntity = (GrailsHibernatePersistentEntity) domainClass; Component id = new Component(metadataBuildingContext, root); id.setNullValue("undefined"); root.setIdentifier(id); @@ -1643,10 +1683,14 @@ public class GrailsDomainBinder * @param mappings The Hibernate Mappings instance * @param sessionFactoryBeanName the session factory bean name */ - private void createClassProperties(HibernatePersistentEntity domainClass, PersistentClass persistentClass, + private void createClassProperties(GrailsHibernatePersistentEntity domainClass, PersistentClass persistentClass, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { - Mapping gormMapping = getMapping(domainClass); + Mapping result = null; + if (domainClass != null) { + result = domainClass.getMappedForm(); + } + Mapping gormMapping = result; Table table = persistentClass.getTable(); table.setComment(gormMapping.getComment()); final List<PersistentProperty> persistentProperties = domainClass.getPersistentProperties() @@ -1814,7 +1858,7 @@ public class GrailsDomainBinder component.setRoleName(role); component.setComponentClassName(type.getName()); - PersistentEntity domainClass = property.getAssociatedEntity(); + GrailsHibernatePersistentEntity domainClass = (GrailsHibernatePersistentEntity) property.getAssociatedEntity(); evaluateMapping(domainClass); final List<PersistentProperty> properties = domainClass.getPersistentProperties(); Table table = component.getOwner().getTable(); @@ -1903,7 +1947,10 @@ public class GrailsDomainBinder private boolean isComponentPropertyNullable(PersistentProperty componentProperty) { if (componentProperty == null) return false; final PersistentEntity domainClass = componentProperty.getOwner(); - final Mapping mapping = getMapping(domainClass); + Mapping mapping = null; + if (domainClass != null) { + mapping = ((GrailsHibernatePersistentEntity) domainClass).getMappedForm(); + } return !domainClass.isRoot() && (mapping == null || mapping.isTablePerHierarchy()) || componentProperty.isNullable(); } @@ -1981,7 +2028,11 @@ public class GrailsDomainBinder if (pc.getIndexColumn() != null && pc.getIndexColumn().getType() != null) { - Mapping mapping = getMapping(property.getOwner()); + Mapping mapping = null; + GrailsHibernatePersistentEntity domainClass = (GrailsHibernatePersistentEntity) property.getOwner(); + if (domainClass != null) { + mapping = domainClass.getMappedForm(); + } return new TypeNameProvider().getTypeName(property, mapping); @@ -2019,7 +2070,7 @@ public class GrailsDomainBinder @Override public String getContributorName() { - return AdditionalMappingContributor.super.getContributorName(); + return "GORM"; } @@ -2235,7 +2286,11 @@ public class GrailsDomainBinder } public String getTypeName(ToMany property) { - Mapping mapping = getMapping(property.getOwner()); + Mapping mapping = null; + GrailsHibernatePersistentEntity domainClass = (GrailsHibernatePersistentEntity) property.getOwner(); + if (domainClass != null) { + mapping = domainClass.getMappedForm(); + } return new TypeNameProvider().getTypeName(property, mapping); } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntity.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntity.java new file mode 100644 index 0000000000..774d01da84 --- /dev/null +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntity.java @@ -0,0 +1,19 @@ +package org.grails.orm.hibernate.cfg; + +import org.grails.datastore.mapping.model.PersistentEntity; +import org.grails.datastore.mapping.model.PersistentProperty; + +/** + * Common interface for Hibernate persistent entities + */ +public interface GrailsHibernatePersistentEntity extends PersistentEntity { + Mapping getMappedForm(); + + boolean forGrailsDomainMapping(String dataSourceName); + + boolean usesConnectionSource(String dataSourceName); + + PersistentProperty[] getCompositeIdentity(); + + boolean isAbstract(); +} diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java index ff5631f717..b392d08707 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java @@ -220,7 +220,7 @@ public class GrailsHibernateUtil extends HibernateRuntimeUtils { public static boolean isMappedWithHibernate(PersistentEntity domainClass) { - return domainClass instanceof HibernatePersistentEntity; + return domainClass instanceof GrailsHibernatePersistentEntity; } public static String qualify(final String prefix, final String name) { diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateEmbeddedPersistentEntity.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateEmbeddedPersistentEntity.java index f1b677338d..e0ba4369a8 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateEmbeddedPersistentEntity.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateEmbeddedPersistentEntity.java @@ -1,18 +1,35 @@ package org.grails.orm.hibernate.cfg; -import org.grails.datastore.mapping.model.ClassMapping; -import org.grails.datastore.mapping.model.EmbeddedPersistentEntity; -import org.grails.datastore.mapping.model.IdentityMapping; -import org.grails.datastore.mapping.model.MappingContext; -import org.grails.datastore.mapping.model.PersistentEntity; +import org.grails.datastore.mapping.core.connections.ConnectionSourcesSupport; +import org.grails.datastore.mapping.model.*; -public class HibernateEmbeddedPersistentEntity extends EmbeddedPersistentEntity<Mapping> { +public class HibernateEmbeddedPersistentEntity extends EmbeddedPersistentEntity<Mapping> implements GrailsHibernatePersistentEntity { private final ClassMapping<Mapping> classMapping; public Mapping getMappedForm() { return classMapping.getMappedForm(); } + @Override + public boolean forGrailsDomainMapping(String dataSourceName) { + return false; + } + + @Override + public boolean usesConnectionSource(String dataSourceName) { + return ConnectionSourcesSupport.usesConnectionSource(this, dataSourceName); + } + + @Override + public PersistentProperty[] getCompositeIdentity() { + return null; + } + + @Override + public boolean isAbstract() { + return false; + } + public HibernateEmbeddedPersistentEntity(Class type, MappingContext ctx) { super(type, ctx); this.classMapping = new ClassMapping<Mapping>() { 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 cde929dd87..d0e3d04cbc 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 @@ -190,12 +190,12 @@ public class HibernateMappingContext extends AbstractMappingContext { return super.getPersistentEntity(name); } - public Collection<HibernatePersistentEntity> getHibernatePersistentEntities() { + public Collection<GrailsHibernatePersistentEntity> getHibernatePersistentEntities() { return Optional.ofNullable(persistentEntities) .orElse(new ArrayList<>()) .stream() - .filter(HibernatePersistentEntity.class::isInstance) - .map(HibernatePersistentEntity.class::cast) + .filter(GrailsHibernatePersistentEntity.class::isInstance) + .map(GrailsHibernatePersistentEntity.class::cast) .toList(); } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernatePersistentEntity.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernatePersistentEntity.java index af8b90e4e6..458d3a8223 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernatePersistentEntity.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernatePersistentEntity.java @@ -28,7 +28,7 @@ import jakarta.persistence.Entity; * @author Graeme Rocher * @since 5.0 */ -public class HibernatePersistentEntity extends AbstractPersistentEntity<Mapping> { +public class HibernatePersistentEntity extends AbstractPersistentEntity<Mapping> implements GrailsHibernatePersistentEntity { private final AbstractClassMapping<Mapping> classMapping; diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/MappingCacheHolder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/MappingCacheHolder.java new file mode 100644 index 0000000000..582ba9822f --- /dev/null +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/MappingCacheHolder.java @@ -0,0 +1,50 @@ +package org.grails.orm.hibernate.cfg; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Holder for the GORM mapping cache. + */ +public class MappingCacheHolder { + + private static final MappingCacheHolder INSTANCE = new MappingCacheHolder(); + + private MappingCacheHolder() {} + + public static MappingCacheHolder getInstance() { + return INSTANCE; + } + + private final Map<Class<?>, Mapping> MAPPING_CACHE = new HashMap<>(); + + + /** + * Obtains a mapping object for the given domain class nam + * + * @param theClass The domain class in question + * @return A Mapping object or null + */ + public Mapping getMapping(Class<?> theClass) { + return theClass == null ? null : MAPPING_CACHE.get(theClass); + } + + public void cacheMapping(Class<?> theClass, Mapping mapping) { + MAPPING_CACHE.put(theClass, mapping); + } + + public void clear() { + MAPPING_CACHE.clear(); + } + + public void clear(Class<?> theClass) { + String className = theClass.getName(); + for (Iterator<Map.Entry<Class<?>, Mapping>> it = MAPPING_CACHE.entrySet().iterator(); it.hasNext(); ) { + Map.Entry<Class<?>, Mapping> entry = it.next(); + if (className.equals(entry.getKey().getName())) { + it.remove(); + } + } + } +} diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreator.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreator.java index e1d7ffc549..6514b20181 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreator.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreator.java @@ -15,18 +15,18 @@ import org.hibernate.id.uuid.UuidGenerator; import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.RootClass; -import org.grails.orm.hibernate.cfg.HibernatePersistentEntity; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Identity; public class BasicValueIdCreator { private final JdbcEnvironment jdbcEnvironment; - private HibernatePersistentEntity domainClass; + private GrailsHibernatePersistentEntity domainClass; private final Map<String, BiFunction<GeneratorCreationContext, Identity, Generator>> generatorFactories; @SuppressWarnings("unused") // kept for tests that want to provide a prototype BasicValue private final BasicValue id; - public BasicValueIdCreator(MetadataBuildingContext metadataBuildingContext, JdbcEnvironment jdbcEnvironment, HibernatePersistentEntity domainClass, RootClass entity) { + public BasicValueIdCreator(MetadataBuildingContext metadataBuildingContext, JdbcEnvironment jdbcEnvironment, GrailsHibernatePersistentEntity domainClass, RootClass entity) { // create a prototype BasicValue (table will be set per-entity when creating the actual BasicValue) this(jdbcEnvironment, new BasicValue(metadataBuildingContext, entity.getTable()), new HashMap<>()); this.domainClass = domainClass; diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorFetcher.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorFetcher.java index ef1f0d0fbb..ae79098f73 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorFetcher.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorFetcher.java @@ -4,7 +4,7 @@ import org.grails.datastore.mapping.model.PersistentProperty; import org.grails.datastore.mapping.model.types.Association; import org.grails.datastore.mapping.model.types.Basic; import org.grails.datastore.mapping.model.types.Embedded; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PropertyConfig; import org.hibernate.MappingException; @@ -85,7 +85,10 @@ public class CascadeBehaviorFetcher { } private Mapping getOwnersWrappedForm(Association<?> association) { - return GrailsDomainBinder.getMapping(association.getOwner()); + if (association.getOwner() instanceof GrailsHibernatePersistentEntity) { + return ((GrailsHibernatePersistentEntity) association.getOwner()).getMappedForm(); + } + return null; } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinder.java index db7b5cee35..aa426fec7a 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinder.java @@ -12,7 +12,7 @@ import org.grails.datastore.mapping.model.types.ManyToMany; import org.grails.datastore.mapping.model.types.OneToOne; import org.grails.datastore.mapping.model.types.ToOne; import org.grails.orm.hibernate.cfg.ColumnConfig; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; import org.grails.orm.hibernate.cfg.PropertyConfig; @@ -119,8 +119,11 @@ public class ColumnBinder { final PersistentEntity owner = property.getOwner(); if (!owner.isRoot()) { - Mapping mapping = GrailsDomainBinder.getMapping(owner); - if (mapping.getTablePerHierarchy()) { + Mapping mapping = null; + if (owner instanceof GrailsHibernatePersistentEntity) { + mapping = ((GrailsHibernatePersistentEntity) owner).getMappedForm(); + } + if (mapping != null && mapping.getTablePerHierarchy()) { if (LOG.isDebugEnabled()) LOG.debug("[GrailsDomainBinder] Sub class property [" + property.getName() + "] for column name ["+column.getName()+"] set to nullable"); column.setNullable(true); diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java index 004336738c..3e109620a5 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java @@ -2,7 +2,7 @@ package org.grails.orm.hibernate.cfg.domainbinding; import org.grails.datastore.mapping.model.PersistentProperty; import org.grails.orm.hibernate.cfg.ColumnConfig; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.IdentityEnumType; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PropertyConfig; @@ -40,7 +40,10 @@ public class EnumTypeBinder { public void bindEnumType(PersistentProperty property, Class<?> propertyType, SimpleValue simpleValue, String columnName) { PropertyConfig pc = new PersistentPropertyToPropertyConfig().toPropertyConfig(property); - Mapping ownerMapping = GrailsDomainBinder.getMapping(property.getOwner()); + Mapping ownerMapping = null; + if (property.getOwner() instanceof GrailsHibernatePersistentEntity) { + ownerMapping = ((GrailsHibernatePersistentEntity) property.getOwner()).getMappedForm(); + } String enumType = pc.getEnumType(); Properties enumProperties = new Properties(); enumProperties.put(ENUM_CLASS_PROP, propertyType.getName()); diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIncrementGenerator.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIncrementGenerator.java index 04e7d0f004..bc8ef34fb7 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIncrementGenerator.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIncrementGenerator.java @@ -1,17 +1,20 @@ package org.grails.orm.hibernate.cfg.domainbinding; -import org.grails.orm.hibernate.cfg.HibernatePersistentEntity; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Identity; import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.generator.GeneratorCreationContext; import org.hibernate.id.IncrementGenerator; import java.util.Properties; public class GrailsIncrementGenerator extends IncrementGenerator { - public GrailsIncrementGenerator(GeneratorCreationContext context, Identity mappedId, JdbcEnvironment jdbcEnvironment, HibernatePersistentEntity domainClass) { + private boolean initialized = false; + + public GrailsIncrementGenerator(GeneratorCreationContext context, Identity mappedId, JdbcEnvironment jdbcEnvironment, GrailsHibernatePersistentEntity domainClass) { Properties params = new Properties(); if (mappedId != null && mappedId.getProperties() != null) { params.putAll(mappedId.getProperties()); @@ -36,6 +39,19 @@ public class GrailsIncrementGenerator extends IncrementGenerator { this.configure(context.getType(), params, context.getServiceRegistry()); } + @Override + public Object generate(SharedSessionContractImplementor session, Object object) { + if (!initialized) { + synchronized (this) { + if (!initialized) { + this.initialize(session.getFactory().getSqlStringGenerationContext()); + initialized = true; + } + } + } + return super.generate(session, object); + } + @Override public void registerExportables(Database database) { // Hibernate 7 IncrementGenerator tries to register table exportables diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinder.java index 86529f5902..fda5740928 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinder.java @@ -1,7 +1,6 @@ package org.grails.orm.hibernate.cfg.domainbinding; import org.hibernate.MappingException; -import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.mapping.Column; import org.hibernate.mapping.ManyToOne; @@ -11,7 +10,7 @@ import org.grails.datastore.mapping.model.types.ManyToMany; import org.grails.datastore.mapping.model.types.OneToOne; import org.grails.orm.hibernate.cfg.ColumnConfig; import org.grails.orm.hibernate.cfg.CompositeIdentity; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.JoinTable; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; @@ -62,9 +61,12 @@ public class ManyToOneBinder { ,String path) { manyToOneValuesBinder.bindManyToOneValues(property, manyToOne); PersistentEntity refDomainClass = property instanceof ManyToMany ? property.getOwner() : property.getAssociatedEntity(); - Mapping mapping = GrailsDomainBinder.getMapping(refDomainClass); + Mapping mapping = null; + if (refDomainClass instanceof GrailsHibernatePersistentEntity) { + mapping = ((GrailsHibernatePersistentEntity) refDomainClass).getMappedForm(); + } - boolean isComposite = mapping.hasCompositeIdentifier(); + boolean isComposite = mapping != null && mapping.hasCompositeIdentifier(); if (isComposite) { CompositeIdentity ci = (CompositeIdentity) mapping.getIdentity(); compositeIdentifierToManyToOneBinder.bindCompositeIdentifierToManyToOne(property, manyToOne, ci, refDomainClass, path); @@ -73,7 +75,7 @@ public class ManyToOneBinder { if (property.isCircular() && (property instanceof ManyToMany)) { PropertyConfig pc = persistentPropertyToPropertyConfig.toPropertyConfig(property); - if (pc.getColumns().isEmpty()) { + if (mapping != null && pc.getColumns().isEmpty()) { mapping.getColumns().put(property.getName(), pc); } if (!pc.hasJoinKeyMapping()) { diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/RootMappingFetcher.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/RootMappingFetcher.java index 741e590689..ee75d0a3e9 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/RootMappingFetcher.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/RootMappingFetcher.java @@ -3,7 +3,7 @@ package org.grails.orm.hibernate.cfg.domainbinding; import java.util.Optional; import org.grails.datastore.mapping.model.PersistentEntity; -import org.grails.orm.hibernate.cfg.HibernatePersistentEntity; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Mapping; public class RootMappingFetcher { @@ -11,9 +11,9 @@ public class RootMappingFetcher { public Mapping getRootMapping(PersistentEntity referenced) { return Optional.ofNullable(referenced) .map(PersistentEntity::getRootEntity) - .filter(HibernatePersistentEntity.class::isInstance) - .map(HibernatePersistentEntity.class::cast) - .map(HibernatePersistentEntity::getMappedForm) + .filter(GrailsHibernatePersistentEntity.class::isInstance) + .map(GrailsHibernatePersistentEntity.class::cast) + .map(GrailsHibernatePersistentEntity::getMappedForm) .orElse(null); } } 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 b1ffba9195..09512b0a0a 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 @@ -9,9 +9,9 @@ import org.hibernate.mapping.RootClass; import org.hibernate.mapping.Table; import org.grails.datastore.mapping.model.PersistentProperty; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; -import org.grails.orm.hibernate.cfg.HibernatePersistentEntity; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Identity; +import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; import static org.grails.orm.hibernate.cfg.GrailsDomainBinder.EMPTY_PATH; @@ -22,7 +22,7 @@ public class SimpleIdBinder { private final SimpleValueBinder simpleValueBinder; private final PropertyBinder propertyBinder; - public SimpleIdBinder(MetadataBuildingContext metadataBuildingContext, PersistentEntityNamingStrategy namingStrategy, JdbcEnvironment jdbcEnvironment, HibernatePersistentEntity domainClass, RootClass entity) { + public SimpleIdBinder(MetadataBuildingContext metadataBuildingContext, PersistentEntityNamingStrategy namingStrategy, JdbcEnvironment jdbcEnvironment, GrailsHibernatePersistentEntity domainClass, RootClass entity) { this.basicValueIdCreator = new BasicValueIdCreator(metadataBuildingContext, jdbcEnvironment, domainClass, entity); this.simpleValueBinder =new SimpleValueBinder(namingStrategy); this.propertyBinder = new PropertyBinder(); @@ -37,7 +37,11 @@ public class SimpleIdBinder { public void bindSimpleId(PersistentProperty identifier, RootClass entity, Identity mappedId) { - boolean useSequence = GrailsDomainBinder.getMapping(identifier.getOwner()).isTablePerConcreteClass(); + Mapping result = null; + if (identifier.getOwner() instanceof GrailsHibernatePersistentEntity) { + result = ((GrailsHibernatePersistentEntity) identifier.getOwner()).getMappedForm(); + } + boolean useSequence = result != null && result.isTablePerConcreteClass(); // create the id value BasicValue id = basicValueIdCreator.getBasicValueId(entity, mappedId, useSequence); diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinder.java index d0dc7fa123..3cb01638c3 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinder.java @@ -14,7 +14,7 @@ import org.hibernate.mapping.Table; import org.grails.datastore.mapping.model.PersistentProperty; import org.grails.datastore.mapping.model.types.TenantId; import org.grails.orm.hibernate.cfg.ColumnConfig; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; import org.grails.orm.hibernate.cfg.PropertyConfig; @@ -65,10 +65,16 @@ public class SimpleValueBinder { , String path ) { PropertyConfig propertyConfig = persistentPropertyToPropertyConfig.toPropertyConfig(property); - Mapping mapping = GrailsDomainBinder.getMapping(property.getOwner()); + Mapping mapping = null; + if (property.getOwner() instanceof GrailsHibernatePersistentEntity) { + mapping = ((GrailsHibernatePersistentEntity) property.getOwner()).getMappedForm(); + } final String typeName = typeNameProvider.getTypeName(property, mapping); if (typeName == null) { - simpleValue.setTypeName(property.getType().getName()); + Class<?> type = property.getType(); + if (type != null) { + simpleValue.setTypeName(type.getName()); + } } else { simpleValue.setTypeName(typeName); diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcher.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcher.java index a66fcc3170..d928dd5bf1 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcher.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcher.java @@ -1,9 +1,7 @@ package org.grails.orm.hibernate.cfg.domainbinding; -import java.util.Optional; - import org.grails.datastore.mapping.model.PersistentEntity; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; @@ -20,7 +18,11 @@ public class TableNameFetcher { } public String getTableName(PersistentEntity domainClass) { - var tableName = GrailsDomainBinder.getMapping(domainClass).getTableName(); + Mapping result = null; + if (domainClass instanceof GrailsHibernatePersistentEntity) { + result = ((GrailsHibernatePersistentEntity) domainClass).getMappedForm(); + } + var tableName = result != null ? result.getTableName() : null; return tableName != null ? tableName :persistentEntityNamingStrategy.resolveTableName(domainClass); } } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java index 8195a0e9c0..b0ed635e8d 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java @@ -2,13 +2,14 @@ package org.grails.orm.hibernate.query; import org.grails.datastore.mapping.config.Property; import org.grails.datastore.mapping.reflect.ClassUtils; -import org.grails.orm.hibernate.cfg.GrailsDomainBinder; import org.grails.orm.hibernate.cfg.Mapping; import org.grails.datastore.gorm.finders.DynamicFinder; import org.grails.datastore.mapping.model.PersistentEntity; import org.grails.datastore.mapping.model.PersistentProperty; import org.grails.datastore.mapping.model.types.Association; import org.grails.datastore.mapping.model.types.Embedded; +import org.grails.orm.hibernate.cfg.MappingCacheHolder; + import org.hibernate.FetchMode; import org.hibernate.FlushMode; import org.hibernate.query.Query; @@ -86,7 +87,8 @@ public class GrailsHibernateQueryUtils { addOrderPossiblyNested(query, queryRoot, criteriaBuilder,entity, sort, order, ignoreCase); } } else if (useDefaultMapping) { - Mapping m = GrailsDomainBinder.getMapping(entity.getJavaClass()); + Class<?> theClass = entity.getJavaClass(); + Mapping m = MappingCacheHolder.getInstance().getMapping(theClass); if (m != null) { Map sortMap = m.getSort().getNamesAndDirections(); for (Object sort : sortMap.keySet()) { @@ -278,7 +280,7 @@ public class GrailsHibernateQueryUtils { * @param criteria The criteria */ private static void cacheCriteriaByMapping(Class<?> targetClass, Query criteria) { - Mapping m = GrailsDomainBinder.getMapping(targetClass); + Mapping m = MappingCacheHolder.getInstance().getMapping(targetClass); if (m != null && m.getCache() != null && m.getCache().getEnabled()) { criteria.setCacheable(true); } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinderSpec.groovy index 398ce49631..0df1ccf6d4 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ColumnBinderSpec.groovy @@ -4,6 +4,7 @@ import org.grails.datastore.mapping.model.PersistentEntity import org.grails.datastore.mapping.model.PersistentProperty import org.grails.datastore.mapping.model.types.ManyToMany import org.grails.orm.hibernate.cfg.ColumnConfig +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity import org.grails.orm.hibernate.cfg.Mapping import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy import org.grails.orm.hibernate.cfg.PropertyConfig @@ -36,7 +37,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(ManyToMany) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mappedForm = Mock(PropertyConfig) def column = new Column() def table = new Table() @@ -87,7 +88,7 @@ class ColumnBinderSpec extends Specification { def prop = Mock(PersistentProperty) def parentProp = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def propertyConfig = Mock(PropertyConfig) def column = new Column("test") @@ -151,7 +152,7 @@ class ColumnBinderSpec extends Specification { def prop = Mock(org.grails.datastore.mapping.model.types.OneToOne) def inverse = Mock(org.grails.datastore.mapping.model.types.Association) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mappedForm = Mock(PropertyConfig) def column = new Column("pre_existing") def table = new Table() @@ -205,7 +206,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def propertyConfig = Mock(PropertyConfig) def column = new Column("test") def table = new Table() @@ -256,7 +257,7 @@ class ColumnBinderSpec extends Specification { def prop = Mock(org.grails.datastore.mapping.model.types.OneToOne) def inverse = Mock(org.grails.datastore.mapping.model.types.Association) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mappedForm = Mock(PropertyConfig) def column = new Column() // name is null so binder should set it def table = new Table() @@ -309,7 +310,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(org.grails.datastore.mapping.model.types.ToOne) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mappedForm = Mock(PropertyConfig) def column = new Column() def table = new Table() @@ -359,7 +360,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(org.grails.datastore.mapping.model.types.Association) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mappedForm = Mock(PropertyConfig) def column = new Column() def table = new Table() @@ -411,7 +412,7 @@ class ColumnBinderSpec extends Specification { def prop = Mock(PersistentProperty) def parentProp = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def propertyConfig = Mock(PropertyConfig) def column = new Column("test") def table = new Table() @@ -462,7 +463,7 @@ class ColumnBinderSpec extends Specification { def prop = Mock(PersistentProperty) def parentProp = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def propertyConfig = Mock(PropertyConfig) def column = new Column("test") def table = new Table() @@ -511,7 +512,7 @@ class ColumnBinderSpec extends Specification { def prop = Mock(PersistentProperty) def parentProp = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def propertyConfig = Mock(PropertyConfig) def column = new Column("test") def table = new Table() @@ -559,7 +560,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def column = new Column("test") def table = new Table() @@ -606,7 +607,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def column = new Column("test") def table = new Table() @@ -655,7 +656,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def column = new Column("test") def table = new Table() @@ -703,7 +704,7 @@ class ColumnBinderSpec extends Specification { ) def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def propertyConfig = Mock(PropertyConfig) def column = new Column("test") diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinderSpec.groovy index 9e99245353..519404ad8d 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ManyToOneBinderSpec.groovy @@ -6,6 +6,7 @@ import org.grails.datastore.mapping.model.types.Association import org.grails.datastore.mapping.model.types.ManyToMany import org.grails.datastore.mapping.model.types.OneToOne import org.grails.orm.hibernate.cfg.CompositeIdentity +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity import org.grails.orm.hibernate.cfg.JoinTable import org.grails.orm.hibernate.cfg.Mapping import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy @@ -34,7 +35,7 @@ class ManyToOneBinderSpec extends HibernateGormDatastoreSpec { def manyToOne = new ManyToOne(getGrailsDomainBinder().getMetadataBuildingContext(), null) def path = "/test" def mapping = new Mapping() - def refDomainClass = Mock(PersistentEntity) { + def refDomainClass = Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } def propertyConfig = new PropertyConfig() @@ -72,7 +73,7 @@ class ManyToOneBinderSpec extends HibernateGormDatastoreSpec { def manyToOne = new ManyToOne(getGrailsDomainBinder().getMetadataBuildingContext(), null) def mapping = new Mapping() mapping.setColumns(new HashMap<String, PropertyConfig>()) - def ownerEntity = Mock(PersistentEntity) { + def ownerEntity = Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } def propertyConfig = new PropertyConfig() @@ -109,7 +110,7 @@ class ManyToOneBinderSpec extends HibernateGormDatastoreSpec { def property = Mock(OneToOne) def manyToOne = new ManyToOne(getGrailsDomainBinder().getMetadataBuildingContext(), null) def mapping = new Mapping() - def refDomainClass = Mock(PersistentEntity) { + def refDomainClass = Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } def propertyConfig = Mock(PropertyConfig) @@ -161,7 +162,7 @@ class ManyToOneBinderSpec extends HibernateGormDatastoreSpec { def property = Mock(OneToOne) def manyToOne = new ManyToOne(getGrailsDomainBinder().getMetadataBuildingContext(), null) def mapping = new Mapping() - def refDomainClass = Mock(PersistentEntity) { + def refDomainClass = Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } def propertyConfig = new PropertyConfig() 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 970fbe3a7f..275242d3af 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 @@ -2,7 +2,7 @@ package org.grails.orm.hibernate.cfg.domainbinding import grails.gorm.specs.HibernateGormDatastoreSpec import org.grails.datastore.mapping.model.PersistentProperty -import org.grails.datastore.mapping.model.PersistentEntity +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity import org.grails.orm.hibernate.cfg.Identity import org.hibernate.boot.spi.MetadataBuildingContext import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment @@ -46,7 +46,7 @@ class SimpleIdBinderSpec extends HibernateGormDatastoreSpec { } def testProperty = Mock(PersistentProperty) { getName() >> "id" - getOwner() >> Mock(PersistentEntity) { + getOwner() >> Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } } @@ -74,7 +74,7 @@ class SimpleIdBinderSpec extends HibernateGormDatastoreSpec { } def testProperty = Mock(PersistentProperty) { getName() >> "id" - getOwner() >> Mock(PersistentEntity) { + getOwner() >> Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy index b2f4414ed0..859458f9b5 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy @@ -1,9 +1,9 @@ package org.grails.orm.hibernate.cfg.domainbinding -import org.grails.datastore.mapping.model.PersistentEntity import org.grails.datastore.mapping.model.PersistentProperty import org.grails.datastore.mapping.model.types.TenantId import org.grails.orm.hibernate.cfg.ColumnConfig +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity import org.grails.orm.hibernate.cfg.Mapping import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy import org.grails.orm.hibernate.cfg.PropertyConfig @@ -28,7 +28,7 @@ class SimpleValueBinderSpec extends Specification { def "sets type from provider when present and applies type params"() { given: def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def pc = Mock(PropertyConfig) def sv = Mock(SimpleValue) @@ -65,7 +65,7 @@ class SimpleValueBinderSpec extends Specification { def "falls back to property type when provider returns null"() { given: def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def pc = Mock(PropertyConfig) def sv = Mock(SimpleValue) @@ -95,7 +95,7 @@ class SimpleValueBinderSpec extends Specification { given: def prop = Mock(PersistentProperty) def tenantProp = Mock(TenantId) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def pc = Mock(PropertyConfig) def tenantPc = Mock(PropertyConfig) @@ -135,7 +135,7 @@ class SimpleValueBinderSpec extends Specification { def "applies generator and maps sequence param to SequenceStyleGenerator.SEQUENCE_PARAM"() { given: def prop = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def pc = Mock(PropertyConfig) def sv = Mock(org.hibernate.mapping.BasicValue) @@ -150,6 +150,7 @@ class SimpleValueBinderSpec extends Specification { pc.getColumns() >> null pc.getGenerator() >> 'sequence' pc.getTypeParams() >> genProps + prop.getType() >> String when: binder.bindSimpleValue(prop, null, sv, null) @@ -165,7 +166,7 @@ class SimpleValueBinderSpec extends Specification { given: def prop = Mock(PersistentProperty) def parent = Mock(PersistentProperty) - def owner = Mock(PersistentEntity) + def owner = Mock(GrailsHibernatePersistentEntity) def mapping = Mock(Mapping) def pc = Mock(PropertyConfig) def cc1 = new ColumnConfig(name: 'c1') @@ -181,6 +182,7 @@ class SimpleValueBinderSpec extends Specification { pc.getColumns() >> [cc1, cc2] prop.isNullable() >> true parent.isNullable() >> false + prop.getType() >> String when: binder.bindSimpleValue(prop, parent, sv, 'path') diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcherSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcherSpec.groovy index 8f6c44bfe2..da49d54082 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcherSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableNameFetcherSpec.groovy @@ -1,6 +1,7 @@ package org.grails.orm.hibernate.cfg.domainbinding import org.grails.datastore.mapping.model.PersistentEntity +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity import org.grails.orm.hibernate.cfg.Mapping import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy import spock.lang.Specification @@ -14,7 +15,7 @@ class TableNameFetcherSpec extends Specification { def namingStrategy = Mock(PersistentEntityNamingStrategy) def fetcher = new TableNameFetcher(namingStrategy) def mapping = Mock(Mapping) - def persistentEntity = Mock(PersistentEntity) { + def persistentEntity = Mock(GrailsHibernatePersistentEntity) { getMappedForm() >> mapping } diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/AbstractMappingContext.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/AbstractMappingContext.java index dea811c223..e08a1a1736 100644 --- a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/AbstractMappingContext.java +++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/AbstractMappingContext.java @@ -479,6 +479,7 @@ public abstract class AbstractMappingContext implements MappingContext, Initiali return persistentEntities; } + public boolean isPersistentEntity(Class type) { return type != null && getPersistentEntity(type.getName()) != null;
