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 38349bcf479e6f7fd00306107eaeee89e7751f16 Author: Walter B Duque de Estrada <[email protected]> AuthorDate: Sat Jan 24 18:29:32 2026 -0600 update progress --- .../orm/hibernate/cfg/GrailsDomainBinder.java | 42 +---------- .../hibernate/cfg/domainbinding/VersionBinder.java | 67 +++++++++++++++++ .../cfg/domainbinding/VersionBinderSpec.groovy | 87 ++++++++++++++++++++++ 3 files changed, 155 insertions(+), 41 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 22576856b0..ff2e9a4b36 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 @@ -37,8 +37,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.SimpleValueColumnBinder; import org.grails.orm.hibernate.cfg.domainbinding.TypeNameProvider; import org.grails.orm.hibernate.cfg.domainbinding.*; -import com.sun.jdi.IntegerType; -import com.sun.jdi.LongType; import org.hibernate.FetchMode; import org.hibernate.MappingException; import org.hibernate.boot.ResourceStreamLocator; @@ -1569,7 +1567,7 @@ public class GrailsDomainBinder LOG.debug("[GrailsDomainBinder] Mapping Grails domain class: " + domainClass.getName() + " -> " + root.getTable().getName()); } bindIdentity(domainClass, root, mappings, gormMapping, sessionFactoryBeanName); - bindVersion(domainClass.getVersion(), root, mappings, sessionFactoryBeanName); + new VersionBinder(metadataBuildingContext, namingStrategy).bindVersion(domainClass.getVersion(), root); root.createPrimaryKey(); createClassProperties(domainClass, root, mappings, sessionFactoryBeanName); } @@ -1975,44 +1973,6 @@ public class GrailsDomainBinder } } - private void bindVersion(PersistentProperty version, RootClass entity, - InFlightMetadataCollector mappings, String sessionFactoryBeanName) { - - if (version != null) { - - BasicValue val = new BasicValue(metadataBuildingContext, entity.getTable()); - - // set type - new SimpleValueBinder(namingStrategy).bindSimpleValue(version, null, val, EMPTY_PATH); - - if (val.isTypeSpecified()) { -// if (!(val.getType() instanceof IntegerType || -// val.getType() instanceof LongType || -// val.getType() instanceof TimestampType)) { -// LOG.warn("Invalid version class specified in " + version.getOwner().getName() + -// "; must be one of [int, Integer, long, Long, Timestamp, Date]. Not mapping the version."); -// return; -// } - } - else { - val.setTypeName("version".equals(version.getName()) ? "integer" : "timestamp"); - } - Property prop = new Property(); - prop.setValue(val); - new PropertyBinder().bindProperty(version, prop); - prop.setLazy(false); - val.setNullValue("undefined"); - entity.setVersion(prop); - entity.setDeclaredVersion(prop); - entity.setOptimisticLockStyle(OptimisticLockStyle.VERSION); - entity.addProperty(prop); - } - else { - entity.setOptimisticLockStyle(OptimisticLockStyle.NONE); - } - } - - private String getIndexColumnName(PersistentProperty property, String sessionFactoryBeanName) { PropertyConfig pc = new PersistentPropertyToPropertyConfig().toPropertyConfig(property); if (pc.getIndexColumn() != null && pc.getIndexColumn().getColumn() != null) { diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/VersionBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/VersionBinder.java new file mode 100644 index 0000000000..3fe5964e25 --- /dev/null +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/VersionBinder.java @@ -0,0 +1,67 @@ +package org.grails.orm.hibernate.cfg.domainbinding; + +import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.engine.OptimisticLockStyle; +import org.hibernate.mapping.BasicValue; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.RootClass; +import org.hibernate.mapping.Table; + +import org.grails.datastore.mapping.model.PersistentProperty; +import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; + +import java.util.function.BiFunction; + +import static org.grails.orm.hibernate.cfg.GrailsDomainBinder.EMPTY_PATH; + +public class VersionBinder { + + private final MetadataBuildingContext metadataBuildingContext; + private final SimpleValueBinder simpleValueBinder; + private final PropertyBinder propertyBinder; + private final BiFunction<MetadataBuildingContext, Table, BasicValue> basicValueFactory; + + public VersionBinder(MetadataBuildingContext metadataBuildingContext, PersistentEntityNamingStrategy namingStrategy) { + this(metadataBuildingContext, + new SimpleValueBinder(namingStrategy), + new PropertyBinder(), + BasicValue::new); + } + + protected VersionBinder(MetadataBuildingContext metadataBuildingContext, + SimpleValueBinder simpleValueBinder, + PropertyBinder propertyBinder, + BiFunction<MetadataBuildingContext, Table, BasicValue> basicValueFactory) { + this.metadataBuildingContext = metadataBuildingContext; + this.simpleValueBinder = simpleValueBinder; + this.propertyBinder = propertyBinder; + this.basicValueFactory = basicValueFactory; + } + + public void bindVersion(PersistentProperty version, RootClass entity) { + + if (version != null) { + + BasicValue val = basicValueFactory.apply(metadataBuildingContext, entity.getTable()); + + // set type + simpleValueBinder.bindSimpleValue(version, null, val, EMPTY_PATH); + + if (!val.isTypeSpecified()) { + val.setTypeName("version".equals(version.getName()) ? "integer" : "timestamp"); + } + Property prop = new Property(); + prop.setValue(val); + propertyBinder.bindProperty(version, prop); + prop.setLazy(false); + val.setNullValue("undefined"); + entity.setVersion(prop); + entity.setDeclaredVersion(prop); + entity.setOptimisticLockStyle(OptimisticLockStyle.VERSION); + entity.addProperty(prop); + } + else { + entity.setOptimisticLockStyle(OptimisticLockStyle.NONE); + } + } +} \ No newline at end of file diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/VersionBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/VersionBinderSpec.groovy new file mode 100644 index 0000000000..c9137a57db --- /dev/null +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/VersionBinderSpec.groovy @@ -0,0 +1,87 @@ +package org.grails.orm.hibernate.cfg.domainbinding + +import grails.gorm.specs.HibernateGormDatastoreSpec +import org.grails.datastore.mapping.model.PersistentProperty +import org.hibernate.boot.spi.MetadataBuildingContext +import org.hibernate.engine.OptimisticLockStyle +import org.hibernate.mapping.BasicValue +import org.hibernate.mapping.RootClass +import org.hibernate.mapping.Table +import java.util.function.BiFunction + +class VersionBinderSpec extends HibernateGormDatastoreSpec { + + MetadataBuildingContext metadataBuildingContext + SimpleValueBinder simpleValueBinder + PropertyBinder propertyBinder + BiFunction<MetadataBuildingContext, Table, BasicValue> basicValueFactory + VersionBinder versionBinder + + def setup() { + metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() + simpleValueBinder = Mock(SimpleValueBinder) + propertyBinder = Mock(PropertyBinder) + basicValueFactory = Mock(BiFunction) + + versionBinder = new VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinder, basicValueFactory) + } + + def "should bind version property correctly"() { + given: + def rootClass = new RootClass(metadataBuildingContext) + def table = new Table("TEST_TABLE") + rootClass.setTable(table) + + def versionProperty = Mock(PersistentProperty) { + getName() >> "version" + } + + def basicValue = new BasicValue(metadataBuildingContext, table) + + when: + versionBinder.bindVersion(versionProperty, rootClass) + + then: + 1 * basicValueFactory.apply(metadataBuildingContext, table) >> basicValue + 1 * simpleValueBinder.bindSimpleValue(versionProperty, null, basicValue, "") + 1 * propertyBinder.bindProperty(versionProperty, _) + + rootClass.getVersion() != null + rootClass.getDeclaredVersion() != null + rootClass.getOptimisticLockStyle() == OptimisticLockStyle.VERSION + rootClass.getVersion().getValue() == basicValue + basicValue.getTypeName() == "integer" + } + + def "should set optimistic lock style to NONE if version is null"() { + given: + def rootClass = new RootClass(metadataBuildingContext) + + when: + versionBinder.bindVersion(null, rootClass) + + then: + rootClass.getOptimisticLockStyle() == OptimisticLockStyle.NONE + rootClass.getVersion() == null + } + + def "should default type to timestamp if version property name is not 'version'"() { + given: + def rootClass = new RootClass(metadataBuildingContext) + def table = new Table("TEST_TABLE") + rootClass.setTable(table) + + def versionProperty = Mock(PersistentProperty) { + getName() >> "lastUpdated" + } + + def basicValue = new BasicValue(metadataBuildingContext, table) + + when: + versionBinder.bindVersion(versionProperty, rootClass) + + then: + 1 * basicValueFactory.apply(metadataBuildingContext, table) >> basicValue + basicValue.getTypeName() == "timestamp" + } +}
