From cf69c2683dd66715c8a0a16ee0e82e3bc513f7c7 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 4 Dec 2023 15:56:12 -0600 Subject: [PATCH] HHH-17504 - Ongoing JPA 32 work HHH-17350 - Work on hibernate-models, XSD and JAXB HHH-16114 - Improve boot metamodel binding HHH-15996 - Develop an abstraction for Annotation in annotation processing HHH-16012 - Develop an abstraction for domain model Class refs HHH-15997 - Support for dynamic models in orm.xml HHH-15698 - Support for entity-name in mapping.xsd --- .../bind/internal/AttributeBinding.java | 39 +- .../bind/internal/BasicValueHelper.java | 411 ++++++++++++++++++ .../ColumnBinder.java => ColumnHelper.java} | 10 +- .../bind/internal/IdentifierBinding.java | 12 +- .../bind/internal/RootEntityBinding.java | 7 +- .../bind/internal/SubclassEntityBinding.java | 5 +- .../internal/binders/AttributeBinder.java | 98 ----- .../internal/binders/BasicValueBinder.java | 202 --------- .../bind/internal/binders/TenantIdBinder.java | 129 ------ .../bind/internal/binders/VersionBinder.java | 112 ----- .../bind/tenancy/SimpleTenancyTests.java | 6 +- 11 files changed, 447 insertions(+), 584 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BasicValueHelper.java rename hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/{binders/ColumnBinder.java => ColumnHelper.java} (94%) delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/AttributeBinder.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/BasicValueBinder.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/TenantIdBinder.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/VersionBinder.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/AttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/AttributeBinding.java index 7df9343be9..849c939dc1 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/AttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/AttributeBinding.java @@ -16,8 +16,6 @@ import org.hibernate.annotations.OptimisticLock; import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.models.AnnotationPlacementException; -import org.hibernate.boot.models.bind.internal.binders.BasicValueBinder; -import org.hibernate.boot.models.bind.internal.binders.ColumnBinder; import org.hibernate.boot.models.bind.spi.BindingContext; import org.hibernate.boot.models.bind.spi.BindingOptions; import org.hibernate.boot.models.bind.spi.BindingState; @@ -93,41 +91,38 @@ public class AttributeBinding extends Binding { final BasicValue basicValue = new BasicValue( bindingState.getMetadataBuildingContext() ); final MemberDetails member = attributeMetadata.getMember(); - bindImplicitJavaType( member, property, basicValue ); + BasicValueHelper.bindImplicitJavaType( member, basicValue, bindingOptions, bindingState, bindingContext ); bindMutability( member, property, basicValue ); bindOptimisticLocking( member, property, basicValue ); bindConversion( member, property, basicValue ); processColumn( member, property, basicValue, primaryTable, Column.class ); - BasicValueBinder.bindJavaType( member, property, basicValue, bindingOptions, bindingState, bindingContext ); - BasicValueBinder.bindJdbcType( member, property, basicValue, bindingOptions, bindingState, bindingContext ); - BasicValueBinder.bindLob( member, property, basicValue, bindingOptions, bindingState, bindingContext ); - BasicValueBinder.bindNationalized( + BasicValueHelper.bindJavaType( member, basicValue, bindingOptions, bindingState, bindingContext ); + BasicValueHelper.bindJdbcType( member, basicValue, bindingOptions, bindingState, bindingContext ); + BasicValueHelper.bindLob( member, basicValue, bindingOptions, bindingState, bindingContext ); + BasicValueHelper.bindNationalized( member, - property, basicValue, bindingOptions, bindingState, bindingContext ); - BasicValueBinder.bindEnumerated( + BasicValueHelper.bindEnumerated( member, - property, basicValue, bindingOptions, bindingState, bindingContext ); - BasicValueBinder.bindTemporalPrecision( + BasicValueHelper.bindTemporalPrecision( member, - property, basicValue, bindingOptions, bindingState, bindingContext ); - BasicValueBinder.bindTimeZoneStorage( + BasicValueHelper.bindTimeZoneStorage( member, property, basicValue, @@ -156,13 +151,6 @@ public class AttributeBinding extends Binding { return getProperty(); } - public static void bindImplicitJavaType( - MemberDetails member, - @SuppressWarnings("unused") Property property, - BasicValue basicValue) { - basicValue.setImplicitJavaTypeAccess( (typeConfiguration) -> member.getType().toJavaClass() ); - } - private void bindMutability(MemberDetails member, Property property, BasicValue basicValue) { final var mutabilityAnn = member.getAnnotationUsage( Mutability.class ); final var immutableAnn = member.getAnnotationUsage( Immutable.class ); @@ -236,9 +224,18 @@ public class AttributeBinding extends Binding { BasicValue basicValue, Table primaryTable, Class annotation) { + BasicValueHelper.bindColumn( + member, + property::getName, + basicValue, + primaryTable, + bindingOptions, + bindingState, + bindingContext + ); // todo : implicit column final var columnAnn = member.getAnnotationUsage( annotation ); - final var column = ColumnBinder.bindColumn( columnAnn, property::getName ); + final var column = ColumnHelper.bindColumn( columnAnn, property::getName ); var tableName = BindingHelper.getValue( columnAnn, "table", "" ); if ( "".equals( tableName ) || tableName == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BasicValueHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BasicValueHelper.java new file mode 100644 index 0000000000..a32e83ff7c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BasicValueHelper.java @@ -0,0 +1,411 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.boot.models.bind.internal; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.util.function.Supplier; + +import org.hibernate.MappingException; +import org.hibernate.annotations.JavaType; +import org.hibernate.annotations.JdbcType; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.annotations.Nationalized; +import org.hibernate.annotations.TimeZoneColumn; +import org.hibernate.annotations.TimeZoneStorage; +import org.hibernate.annotations.TimeZoneStorageType; +import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.models.AnnotationPlacementException; +import org.hibernate.boot.models.bind.spi.BindingContext; +import org.hibernate.boot.models.bind.spi.BindingOptions; +import org.hibernate.boot.models.bind.spi.BindingState; +import org.hibernate.boot.models.bind.spi.TableReference; +import org.hibernate.boot.models.categorize.spi.AttributeMetadata; +import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata; +import org.hibernate.boot.spi.InFlightMetadataCollector; +import org.hibernate.engine.spi.FilterDefinition; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.mapping.BasicValue; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.RootClass; +import org.hibernate.mapping.Table; +import org.hibernate.models.ModelsException; +import org.hibernate.models.spi.AnnotationUsage; +import org.hibernate.models.spi.ClassDetails; +import org.hibernate.models.spi.MemberDetails; +import org.hibernate.type.BasicType; +import org.hibernate.type.descriptor.java.BasicJavaType; +import org.hibernate.type.spi.TypeConfiguration; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Lob; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; + +import static jakarta.persistence.EnumType.ORDINAL; +import static java.util.Collections.singletonMap; +import static org.hibernate.annotations.TimeZoneStorageType.AUTO; +import static org.hibernate.annotations.TimeZoneStorageType.COLUMN; + +/** + * @author Steve Ebersole + */ +public class BasicValueHelper { + + public static final String TENANT_FILTER_NAME = "_tenantId"; + public static final String TENANT_PARAMETER_NAME = "tenantId"; + + public static void bindImplicitJavaType( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + basicValue.setImplicitJavaTypeAccess( (typeConfiguration) -> member.getType().toJavaClass() ); + } + + public static void bindJavaType( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + // todo : do we need to account for JavaTypeRegistration here? + final var javaTypeAnn = member.getAnnotationUsage( JavaType.class ); + if ( javaTypeAnn == null ) { + return; + } + + basicValue.setExplicitJavaTypeAccess( (typeConfiguration) -> { + final var classDetails = javaTypeAnn.getClassDetails( "value" ); + final Class> javaClass = classDetails.toJavaClass(); + try { + return javaClass.getConstructor().newInstance(); + } + catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + final ModelsException modelsException = new ModelsException( "Error instantiating local @JavaType - " + member.getName() ); + modelsException.addSuppressed( e ); + throw modelsException; + } + } ); + } + + public static void bindJdbcType( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + // todo : do we need to account for JdbcTypeRegistration here? + final var jdbcTypeAnn = member.getAnnotationUsage( JdbcType.class ); + final var jdbcTypeCodeAnn = member.getAnnotationUsage( JdbcTypeCode.class ); + + if ( jdbcTypeAnn != null ) { + if ( jdbcTypeCodeAnn != null ) { + throw new AnnotationPlacementException( + "Illegal combination of @JdbcType and @JdbcTypeCode - " + member.getName() + ); + } + + basicValue.setExplicitJdbcTypeAccess( (typeConfiguration) -> { + final var classDetails = jdbcTypeAnn.getClassDetails( "value" ); + final Class javaClass = classDetails.toJavaClass(); + try { + return javaClass.getConstructor().newInstance(); + } + catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + final ModelsException modelsException = new ModelsException( "Error instantiating local @JdbcType - " + member.getName() ); + modelsException.addSuppressed( e ); + throw modelsException; + } + } ); + } + else if ( jdbcTypeCodeAnn != null ) { + final Integer typeCode = jdbcTypeCodeAnn.getInteger( "value" ); + basicValue.setExplicitJdbcTypeCode( typeCode ); + } + } + + public static void bindNationalized( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + if ( member.getAnnotationUsage( Nationalized.class ) != null ) { + basicValue.makeNationalized(); + } + } + + public static void bindLob( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + if ( member.getAnnotationUsage( Lob.class ) != null ) { + basicValue.makeLob(); + } + } + + public static void bindEnumerated( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + final AnnotationUsage enumerated = member.getAnnotationUsage( Enumerated.class ); + if ( enumerated == null ) { + return; + } + + basicValue.setEnumerationStyle( enumerated.getEnum( "value", ORDINAL ) ); + } + + public static void bindTemporalPrecision( + MemberDetails member, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + final AnnotationUsage temporalAnn = member.getAnnotationUsage( Temporal.class ); + if ( temporalAnn == null ) { + return; + } + + //noinspection deprecation + final TemporalType precision = temporalAnn.getEnum( "value" ); + basicValue.setTemporalPrecision( precision ); + } + + public static void bindTimeZoneStorage( + MemberDetails member, + Property property, + BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + final AnnotationUsage storageAnn = member.getAnnotationUsage( TimeZoneStorage.class ); + final AnnotationUsage columnAnn = member.getAnnotationUsage( TimeZoneColumn.class ); + if ( storageAnn != null ) { + final TimeZoneStorageType strategy = storageAnn.getEnum( "value", AUTO ); + if ( strategy != COLUMN && columnAnn != null ) { + throw new AnnotationPlacementException( + "Illegal combination of @TimeZoneStorage(" + strategy.name() + ") and @TimeZoneColumn" + ); + } + basicValue.setTimeZoneStorageType( strategy ); + } + + if ( columnAnn != null ) { + final org.hibernate.mapping.Column column = (org.hibernate.mapping.Column) basicValue.getColumn(); + column.setName( columnAnn.getString( "name", property.getName() + "_tz" ) ); + column.setSqlType( columnAnn.getString( "columnDefinition", (String) null ) ); + + final var tableName = columnAnn.getString( "table", (String) null ); + TableReference tableByName = null; + if ( tableName != null ) { + final Identifier identifier = Identifier.toIdentifier( tableName ); + tableByName = bindingState.getTableByName( identifier.getCanonicalName() ); + basicValue.setTable( tableByName.table() ); + } + + property.setInsertable( columnAnn.getBoolean( "insertable", true ) ); + property.setUpdateable( columnAnn.getBoolean( "updatable", true ) ); + } + } + + public static void bindConversion( + MemberDetails member, + @SuppressWarnings("unused") BasicValue basicValue, + @SuppressWarnings("unused") BindingOptions bindingOptions, + @SuppressWarnings("unused") BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + // todo : do we need to account for auto-applied converters here? + final var convertAnn = member.getAnnotationUsage( Convert.class ); + if ( convertAnn == null ) { + return; + } + + if ( convertAnn.getBoolean( "disableConversion" ) ) { + return; + } + + if ( convertAnn.getString( "attributeName" ) != null ) { + throw new ModelsException( "@Convert#attributeName should not be specified on basic mappings - " + member.getName() ); + } + + final ClassDetails converterClassDetails = convertAnn.getClassDetails( "converter" ); + final Class> javaClass = converterClassDetails.toJavaClass(); + basicValue.setJpaAttributeConverterDescriptor( new ClassBasedConverterDescriptor( + javaClass, + bindingContext.getClassmateContext() + ) ); + } + + public static org.hibernate.mapping.Column bindColumn( + MemberDetails member, + Supplier defaultNameSupplier, + BasicValue basicValue, + Table primaryTable, + BindingOptions bindingOptions, + BindingState bindingState, + BindingContext bindingContext) { + return bindColumn( + member, + Column.class, + defaultNameSupplier, + basicValue, + primaryTable, + bindingOptions, + bindingState, + bindingContext + ); + } + + public static org.hibernate.mapping.Column bindColumn( + MemberDetails member, + Class annotationType, + Supplier defaultNameSupplier, + BasicValue basicValue, + Table primaryTable, + @SuppressWarnings("unused") BindingOptions bindingOptions, + BindingState bindingState, + @SuppressWarnings("unused") BindingContext bindingContext) { + final var columnAnn = member.getAnnotationUsage( annotationType ); + final var column = ColumnHelper.bindColumn( columnAnn, defaultNameSupplier ); + + var tableName = BindingHelper.getValue( columnAnn, "table", "" ); + if ( StringHelper.isEmpty( tableName ) ) { + basicValue.setTable( primaryTable ); + } + else { + final Identifier identifier = Identifier.toIdentifier( tableName ); + final TableReference tableByName = bindingState.getTableByName( identifier.getCanonicalName() ); + basicValue.setTable( tableByName.table() ); + } + + basicValue.addColumn( column ); + + return column; + } + + public static void bindTenantId( + EntityTypeMetadata managedType, + RootClass rootClass, + BindingOptions bindingOptions, + BindingState bindingState, + BindingContext bindingContext) { + final AttributeMetadata tenantIdAttribute = managedType.getHierarchy().getTenantIdAttribute(); + if ( tenantIdAttribute == null ) { + return; + } + + final InFlightMetadataCollector collector = bindingState.getMetadataBuildingContext().getMetadataCollector(); + final TypeConfiguration typeConfiguration = collector.getTypeConfiguration(); + + final MemberDetails memberDetails = tenantIdAttribute.getMember(); + final String returnedClassName = memberDetails.getType().getClassName(); + final BasicType tenantIdType = typeConfiguration + .getBasicTypeRegistry() + .getRegisteredType( returnedClassName ); + + final FilterDefinition filterDefinition = collector.getFilterDefinition( TENANT_FILTER_NAME ); + if ( filterDefinition == null ) { + collector.addFilterDefinition( new FilterDefinition( + TENANT_FILTER_NAME, + "", + singletonMap( TENANT_PARAMETER_NAME, tenantIdType ) + ) ); + } + else { + final org.hibernate.type.descriptor.java.JavaType tenantIdTypeJtd = tenantIdType.getJavaTypeDescriptor(); + final org.hibernate.type.descriptor.java.JavaType parameterJtd = filterDefinition + .getParameterJdbcMapping( TENANT_PARAMETER_NAME ) + .getJavaTypeDescriptor(); + if ( !parameterJtd.getJavaTypeClass().equals( tenantIdTypeJtd.getJavaTypeClass() ) ) { + throw new MappingException( + "all @TenantId fields must have the same type: " + + parameterJtd.getJavaType().getTypeName() + + " differs from " + + tenantIdTypeJtd.getJavaType().getTypeName() + ); + } + } + + final Property property = new Property(); + rootClass.addProperty( property ); + property.setName( tenantIdAttribute.getName() ); + + final BasicValue basicValue = new BasicValue( bindingState.getMetadataBuildingContext(), rootClass.getRootTable() ); + property.setValue( basicValue ); + + bindImplicitJavaType( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + bindJavaType( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + bindJdbcType( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + + bindConversion( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + bindEnumerated( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + + BasicValueHelper.bindColumn( + memberDetails, + property::getName, + basicValue, + rootClass.getRootTable(), + bindingOptions, + bindingState, + bindingContext + ); + + property.resetUpdateable( false ); + property.resetOptional( false ); + } + + public static void bindVersion( + EntityTypeMetadata typeMetadata, + RootClass rootClass, + BindingOptions bindingOptions, + BindingState bindingState, + BindingContext bindingContext) { + final AttributeMetadata versionAttribute = typeMetadata.getHierarchy().getVersionAttribute(); + if ( versionAttribute == null ) { + return; + } + + final Property property = new Property(); + property.setName( versionAttribute.getName() ); + rootClass.setVersion( property ); + rootClass.addProperty( property ); + + final BasicValue basicValue = new BasicValue( + bindingState.getMetadataBuildingContext(), + rootClass.getRootTable() + ); + property.setValue( basicValue ); + + final MemberDetails memberDetails = versionAttribute.getMember(); + bindImplicitJavaType( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + bindJavaType( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + bindJdbcType( memberDetails, basicValue, bindingOptions, bindingState, bindingContext ); + + final org.hibernate.mapping.Column column = bindColumn( + memberDetails, + property::getName, + basicValue, + rootClass.getRootTable(), + bindingOptions, + bindingState, + bindingContext + ); + // force it to be non-nullable + column.setNullable( false ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/ColumnBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/ColumnHelper.java similarity index 94% rename from hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/ColumnBinder.java rename to hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/ColumnHelper.java index 422680772a..3f30036e04 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/ColumnBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/ColumnHelper.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. */ -package org.hibernate.boot.models.bind.internal.binders; +package org.hibernate.boot.models.bind.internal; import java.util.function.Supplier; @@ -28,7 +28,7 @@ import static org.hibernate.internal.util.NullnessHelper.nullif; /** * @author Steve Ebersole */ -public class ColumnBinder { +public class ColumnHelper { public static Column bindColumn( AnnotationUsage annotationUsage, Supplier defaultNameSupplier) { @@ -90,7 +90,7 @@ public class ColumnBinder { return nullif( columnAnnotation.getAttributeValue( "name" ), defaultNameSupplier ); } - private ColumnBinder() { + private ColumnHelper() { } public static DiscriminatorType bindDiscriminatorColumn( diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/IdentifierBinding.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/IdentifierBinding.java index 2aa57b62b1..4e319a9487 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/IdentifierBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/IdentifierBinding.java @@ -6,8 +6,6 @@ */ package org.hibernate.boot.models.bind.internal; -import org.hibernate.boot.models.bind.internal.binders.BasicValueBinder; -import org.hibernate.boot.models.bind.internal.binders.ColumnBinder; import org.hibernate.boot.models.bind.spi.BindingContext; import org.hibernate.boot.models.bind.spi.BindingOptions; import org.hibernate.boot.models.bind.spi.BindingState; @@ -106,7 +104,7 @@ public class IdentifierBinding extends Binding { final PrimaryKey primaryKey = table.getPrimaryKey(); final AnnotationUsage idColumnAnn = idAttributeMember.getAnnotationUsage( Column.class ); - final org.hibernate.mapping.Column column = ColumnBinder.bindColumn( + final org.hibernate.mapping.Column column = ColumnHelper.bindColumn( idColumnAnn, () -> "id", true, @@ -115,10 +113,10 @@ public class IdentifierBinding extends Binding { idValue.addColumn( column, true, false ); primaryKey.addColumn( column ); - AttributeBinding.bindImplicitJavaType( idAttributeMember, idProperty, idValue ); - BasicValueBinder.bindJavaType( idAttributeMember, idProperty, idValue, options, state, context ); - BasicValueBinder.bindJdbcType( idAttributeMember, idProperty, idValue, options, state, context ); - BasicValueBinder.bindNationalized( idAttributeMember, idProperty, idValue, options, state, context ); + BasicValueHelper.bindImplicitJavaType( idAttributeMember, idValue, options, state, context ); + BasicValueHelper.bindJavaType( idAttributeMember, idValue, options, state, context ); + BasicValueHelper.bindJdbcType( idAttributeMember, idValue, options, state, context ); + BasicValueHelper.bindNationalized( idAttributeMember, idValue, options, state, context ); return idValue; } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/RootEntityBinding.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/RootEntityBinding.java index 3648d71a56..5382a76807 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/RootEntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/RootEntityBinding.java @@ -16,7 +16,6 @@ import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.boot.model.relational.Database; -import org.hibernate.boot.models.bind.internal.binders.ColumnBinder; import org.hibernate.boot.models.bind.spi.BindingContext; import org.hibernate.boot.models.bind.spi.BindingOptions; import org.hibernate.boot.models.bind.spi.BindingState; @@ -40,8 +39,8 @@ import jakarta.persistence.DiscriminatorType; import jakarta.persistence.InheritanceType; import static org.hibernate.boot.models.bind.ModelBindingLogging.MODEL_BINDING_LOGGER; -import static org.hibernate.boot.models.bind.internal.binders.TenantIdBinder.bindTenantId; -import static org.hibernate.boot.models.bind.internal.binders.VersionBinder.bindVersion; +import static org.hibernate.boot.models.bind.internal.BasicValueHelper.bindTenantId; +import static org.hibernate.boot.models.bind.internal.BasicValueHelper.bindVersion; import static org.hibernate.internal.util.StringHelper.coalesce; /** @@ -304,7 +303,7 @@ public class RootEntityBinding extends EntityBinding { final BasicValue value = new BasicValue( bindingState.getMetadataBuildingContext(), rootClass.getIdentityTable() ); rootClass.setDiscriminator( value ); - final DiscriminatorType discriminatorType = ColumnBinder.bindDiscriminatorColumn( + final DiscriminatorType discriminatorType = ColumnHelper.bindDiscriminatorColumn( bindingContext, formulaAnn, value, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/SubclassEntityBinding.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/SubclassEntityBinding.java index 73175cbd57..0dbef6beb5 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/SubclassEntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/SubclassEntityBinding.java @@ -10,7 +10,6 @@ import java.util.Collections; import java.util.List; import org.hibernate.MappingException; -import org.hibernate.boot.models.bind.internal.binders.ColumnBinder; import org.hibernate.boot.models.bind.spi.BindingContext; import org.hibernate.boot.models.bind.spi.BindingOptions; import org.hibernate.boot.models.bind.spi.BindingState; @@ -172,10 +171,10 @@ public class SubclassEntityBinding extends EntityBinding { targetColumn, joinColumnAnns ); - pkColumn = ColumnBinder.bindColumn( joinColumnAnn, targetColumn::getName, true, false ); + pkColumn = ColumnHelper.bindColumn( joinColumnAnn, targetColumn::getName, true, false ); } else { - pkColumn = ColumnBinder.bindColumn( null, targetColumn::getName, true, false ); + pkColumn = ColumnHelper.bindColumn( null, targetColumn::getName, true, false ); } primaryKey.addColumn( pkColumn ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/AttributeBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/AttributeBinder.java deleted file mode 100644 index ba0689ecd8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/AttributeBinder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.bind.internal.binders; - -import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; -import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.models.bind.internal.BindingHelper; -import org.hibernate.boot.models.bind.spi.BindingContext; -import org.hibernate.boot.models.bind.spi.BindingOptions; -import org.hibernate.boot.models.bind.spi.BindingState; -import org.hibernate.boot.models.bind.spi.TableReference; -import org.hibernate.mapping.BasicValue; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.Table; -import org.hibernate.models.ModelsException; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.MemberDetails; - -import jakarta.persistence.AttributeConverter; -import jakarta.persistence.Column; -import jakarta.persistence.Convert; - -/** - * @author Steve Ebersole - */ -public class AttributeBinder { - public static void bindImplicitJavaType( - MemberDetails member, - @SuppressWarnings("unused") Property property, - BasicValue basicValue, - @SuppressWarnings("unused") BindingOptions bindingOptions, - @SuppressWarnings("unused") BindingState bindingState, - @SuppressWarnings("unused") BindingContext bindingContext) { - basicValue.setImplicitJavaTypeAccess( (typeConfiguration) -> member.getType().toJavaClass() ); - } - - - public static org.hibernate.mapping.Column processColumn( - MemberDetails member, - Property property, - BasicValue basicValue, - Table primaryTable, - BindingOptions bindingOptions, - BindingState bindingState, - @SuppressWarnings("unused") BindingContext bindingContext) { - // todo : implicit column - final var columnAnn = member.getAnnotationUsage( Column.class ); - final var column = ColumnBinder.bindColumn( columnAnn, property::getName ); - - var tableName = BindingHelper.getValue( columnAnn, "table", "" ); - if ( "".equals( tableName ) || tableName == null ) { - basicValue.setTable( primaryTable ); - } - else { - final Identifier identifier = Identifier.toIdentifier( tableName ); - final TableReference tableByName = bindingState.getTableByName( identifier.getCanonicalName() ); - basicValue.setTable( tableByName.table() ); - } - - basicValue.addColumn( column ); - - return column; - } - - public static void bindConversion( - MemberDetails member, - @SuppressWarnings("unused") Property property, - @SuppressWarnings("unused") BasicValue basicValue, - @SuppressWarnings("unused") BindingOptions bindingOptions, - @SuppressWarnings("unused") BindingState bindingState, - @SuppressWarnings("unused") BindingContext bindingContext) { - // todo : do we need to account for auto-applied converters here? - final var convertAnn = member.getAnnotationUsage( Convert.class ); - if ( convertAnn == null ) { - return; - } - - if ( convertAnn.getBoolean( "disableConversion" ) ) { - return; - } - - if ( convertAnn.getString( "attributeName" ) != null ) { - throw new ModelsException( "@Convert#attributeName should not be specified on basic mappings - " + member.getName() ); - } - - final ClassDetails converterClassDetails = convertAnn.getClassDetails( "converter" ); - final Class> javaClass = converterClassDetails.toJavaClass(); - basicValue.setJpaAttributeConverterDescriptor( new ClassBasedConverterDescriptor( - javaClass, - bindingContext.getClassmateContext() - ) ); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/BasicValueBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/BasicValueBinder.java deleted file mode 100644 index aea4b93eaf..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/BasicValueBinder.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.bind.internal.binders; - -import java.lang.reflect.InvocationTargetException; - -import org.hibernate.annotations.JavaType; -import org.hibernate.annotations.JdbcType; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.annotations.Nationalized; -import org.hibernate.annotations.TimeZoneColumn; -import org.hibernate.annotations.TimeZoneStorage; -import org.hibernate.annotations.TimeZoneStorageType; -import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.models.AnnotationPlacementException; -import org.hibernate.boot.models.bind.spi.BindingContext; -import org.hibernate.boot.models.bind.spi.BindingOptions; -import org.hibernate.boot.models.bind.spi.BindingState; -import org.hibernate.boot.models.bind.spi.TableReference; -import org.hibernate.mapping.BasicValue; -import org.hibernate.mapping.Property; -import org.hibernate.models.ModelsException; -import org.hibernate.models.spi.AnnotationUsage; -import org.hibernate.models.spi.MemberDetails; -import org.hibernate.type.descriptor.java.BasicJavaType; - -import jakarta.persistence.Enumerated; -import jakarta.persistence.Lob; -import jakarta.persistence.Temporal; -import jakarta.persistence.TemporalType; - -import static jakarta.persistence.EnumType.ORDINAL; -import static org.hibernate.annotations.TimeZoneStorageType.AUTO; -import static org.hibernate.annotations.TimeZoneStorageType.COLUMN; - -/** - * @author Steve Ebersole - */ -public class BasicValueBinder { - - public static void bindJavaType( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - // todo : do we need to account for JavaTypeRegistration here? - final var javaTypeAnn = member.getAnnotationUsage( JavaType.class ); - if ( javaTypeAnn == null ) { - return; - } - - basicValue.setExplicitJavaTypeAccess( (typeConfiguration) -> { - final var classDetails = javaTypeAnn.getClassDetails( "value" ); - final Class> javaClass = classDetails.toJavaClass(); - try { - return javaClass.getConstructor().newInstance(); - } - catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - final ModelsException modelsException = new ModelsException( "Error instantiating local @JavaType - " + member.getName() ); - modelsException.addSuppressed( e ); - throw modelsException; - } - } ); - } - - public static void bindJdbcType( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - // todo : do we need to account for JdbcTypeRegistration here? - final var jdbcTypeAnn = member.getAnnotationUsage( JdbcType.class ); - final var jdbcTypeCodeAnn = member.getAnnotationUsage( JdbcTypeCode.class ); - - if ( jdbcTypeAnn != null ) { - if ( jdbcTypeCodeAnn != null ) { - throw new AnnotationPlacementException( - "Illegal combination of @JdbcType and @JdbcTypeCode - " + member.getName() - ); - } - - basicValue.setExplicitJdbcTypeAccess( (typeConfiguration) -> { - final var classDetails = jdbcTypeAnn.getClassDetails( "value" ); - final Class javaClass = classDetails.toJavaClass(); - try { - return javaClass.getConstructor().newInstance(); - } - catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - final ModelsException modelsException = new ModelsException( "Error instantiating local @JdbcType - " + member.getName() ); - modelsException.addSuppressed( e ); - throw modelsException; - } - } ); - } - else if ( jdbcTypeCodeAnn != null ) { - final Integer typeCode = jdbcTypeCodeAnn.getInteger( "value" ); - basicValue.setExplicitJdbcTypeCode( typeCode ); - } - } - - public static void bindNationalized( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - if ( member.getAnnotationUsage( Nationalized.class ) != null ) { - basicValue.makeNationalized(); - } - } - - public static void bindLob( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - if ( member.getAnnotationUsage( Lob.class ) != null ) { - basicValue.makeLob(); - } - } - - public static void bindEnumerated( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final AnnotationUsage enumerated = member.getAnnotationUsage( Enumerated.class ); - if ( enumerated == null ) { - return; - } - - basicValue.setEnumerationStyle( enumerated.getEnum( "value", ORDINAL ) ); - } - - public static void bindTemporalPrecision( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final AnnotationUsage temporalAnn = member.getAnnotationUsage( Temporal.class ); - if ( temporalAnn == null ) { - return; - } - - //noinspection deprecation - final TemporalType precision = temporalAnn.getEnum( "value" ); - basicValue.setTemporalPrecision( precision ); - } - - public static void bindTimeZoneStorage( - MemberDetails member, - Property property, - BasicValue basicValue, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final AnnotationUsage storageAnn = member.getAnnotationUsage( TimeZoneStorage.class ); - final AnnotationUsage columnAnn = member.getAnnotationUsage( TimeZoneColumn.class ); - if ( storageAnn != null ) { - final TimeZoneStorageType strategy = storageAnn.getEnum( "value", AUTO ); - if ( strategy != COLUMN && columnAnn != null ) { - throw new AnnotationPlacementException( - "Illegal combination of @TimeZoneStorage(" + strategy.name() + ") and @TimeZoneColumn" - ); - } - basicValue.setTimeZoneStorageType( strategy ); - } - - if ( columnAnn != null ) { - final org.hibernate.mapping.Column column = (org.hibernate.mapping.Column) basicValue.getColumn(); - column.setName( columnAnn.getString( "name", property.getName() + "_tz" ) ); - column.setSqlType( columnAnn.getString( "columnDefinition", (String) null ) ); - - final var tableName = columnAnn.getString( "table", (String) null ); - TableReference tableByName = null; - if ( tableName != null ) { - final Identifier identifier = Identifier.toIdentifier( tableName ); - tableByName = bindingState.getTableByName( identifier.getCanonicalName() ); - basicValue.setTable( tableByName.table() ); - } - - property.setInsertable( columnAnn.getBoolean( "insertable", true ) ); - property.setUpdateable( columnAnn.getBoolean( "updatable", true ) ); - } - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/TenantIdBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/TenantIdBinder.java deleted file mode 100644 index c1cc37dd34..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/TenantIdBinder.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.bind.internal.binders; - -import org.hibernate.MappingException; -import org.hibernate.boot.models.bind.spi.BindingContext; -import org.hibernate.boot.models.bind.spi.BindingOptions; -import org.hibernate.boot.models.bind.spi.BindingState; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata; -import org.hibernate.boot.spi.InFlightMetadataCollector; -import org.hibernate.engine.spi.FilterDefinition; -import org.hibernate.mapping.BasicValue; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.RootClass; -import org.hibernate.models.spi.MemberDetails; -import org.hibernate.type.BasicType; -import org.hibernate.type.descriptor.java.JavaType; -import org.hibernate.type.spi.TypeConfiguration; - -import static java.util.Collections.singletonMap; -import static org.hibernate.boot.models.bind.internal.binders.AttributeBinder.bindConversion; -import static org.hibernate.boot.models.bind.internal.binders.AttributeBinder.bindImplicitJavaType; -import static org.hibernate.boot.models.bind.internal.binders.AttributeBinder.processColumn; -import static org.hibernate.boot.models.bind.internal.binders.BasicValueBinder.bindEnumerated; -import static org.hibernate.boot.models.bind.internal.binders.BasicValueBinder.bindJavaType; -import static org.hibernate.boot.models.bind.internal.binders.BasicValueBinder.bindJdbcType; - -/** - * @author Steve Ebersole - */ -public class TenantIdBinder { - public static final String FILTER_NAME = "_tenantId"; - public static final String PARAMETER_NAME = "tenantId"; - - public static void bindTenantId( - EntityTypeMetadata managedType, - RootClass rootClass, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final AttributeMetadata tenantIdAttribute = managedType.getHierarchy().getTenantIdAttribute(); - if ( tenantIdAttribute == null ) { - return; - } - - bindTenantId( tenantIdAttribute, rootClass, bindingOptions, bindingState, bindingContext ); - } - - public static void bindTenantId( - AttributeMetadata attributeMetadata, - RootClass rootClass, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final InFlightMetadataCollector collector = bindingState.getMetadataBuildingContext().getMetadataCollector(); - final TypeConfiguration typeConfiguration = collector.getTypeConfiguration(); - - final MemberDetails memberDetails = attributeMetadata.getMember(); - final String returnedClassName = memberDetails.getType().getClassName(); - final BasicType tenantIdType = typeConfiguration - .getBasicTypeRegistry() - .getRegisteredType( returnedClassName ); - - final FilterDefinition filterDefinition = collector.getFilterDefinition( FILTER_NAME ); - if ( filterDefinition == null ) { - collector.addFilterDefinition( new FilterDefinition( - FILTER_NAME, - "", - singletonMap( PARAMETER_NAME, tenantIdType ) - ) ); - } - else { - final JavaType tenantIdTypeJtd = tenantIdType.getJavaTypeDescriptor(); - final JavaType parameterJtd = filterDefinition - .getParameterJdbcMapping( PARAMETER_NAME ) - .getJavaTypeDescriptor(); - if ( !parameterJtd.getJavaTypeClass().equals( tenantIdTypeJtd.getJavaTypeClass() ) ) { - throw new MappingException( - "all @TenantId fields must have the same type: " - + parameterJtd.getJavaType().getTypeName() - + " differs from " - + tenantIdTypeJtd.getJavaType().getTypeName() - ); - } - } - - final Property property = new Property(); - rootClass.addProperty( property ); - property.setName( attributeMetadata.getName() ); - - final BasicValue basicValue = new BasicValue( bindingState.getMetadataBuildingContext(), rootClass.getRootTable() ); - property.setValue( basicValue ); - - bindImplicitJavaType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindJavaType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindJdbcType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - - bindConversion( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindEnumerated( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - - processColumn( - memberDetails, - property, - basicValue, - rootClass.getRootTable(), - bindingOptions, - bindingState, - bindingContext - ); - - property.resetUpdateable( false ); - property.resetOptional( false ); - } - - public static void bindTenantId( - AttributeMetadata attributeMetadata, - EntityTypeMetadata managedType, - RootClass typeBinding, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - bindTenantId( attributeMetadata, typeBinding, bindingOptions, bindingState, bindingContext ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/VersionBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/VersionBinder.java deleted file mode 100644 index 855facefcc..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/binders/VersionBinder.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.bind.internal.binders; - -import org.hibernate.boot.models.bind.spi.BindingContext; -import org.hibernate.boot.models.bind.spi.BindingOptions; -import org.hibernate.boot.models.bind.spi.BindingState; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata; -import org.hibernate.mapping.BasicValue; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.RootClass; -import org.hibernate.models.spi.MemberDetails; - -import static org.hibernate.boot.models.bind.internal.binders.AttributeBinder.bindImplicitJavaType; -import static org.hibernate.boot.models.bind.internal.binders.AttributeBinder.processColumn; -import static org.hibernate.boot.models.bind.internal.binders.BasicValueBinder.bindJavaType; -import static org.hibernate.boot.models.bind.internal.binders.BasicValueBinder.bindJdbcType; - -/** - * @author Steve Ebersole - */ -public class VersionBinder { - public static void bindVersion( - EntityTypeMetadata typeMetadata, - RootClass rootClass, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final AttributeMetadata versionAttribute = typeMetadata.getHierarchy().getVersionAttribute(); - if ( versionAttribute == null ) { - return; - } - - bindVersion( versionAttribute, rootClass, bindingOptions, bindingState, bindingContext ); - } - - public static void bindVersion( - AttributeMetadata versionAttribute, - RootClass typeBinding, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final Property property = new Property(); - property.setName( versionAttribute.getName() ); - typeBinding.setVersion( property ); - typeBinding.addProperty( property ); - - final BasicValue basicValue = new BasicValue( - bindingState.getMetadataBuildingContext(), - typeBinding.getRootTable() - ); - property.setValue( basicValue ); - - final MemberDetails memberDetails = versionAttribute.getMember(); - bindImplicitJavaType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindJavaType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindJdbcType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - - final org.hibernate.mapping.Column column = processColumn( - memberDetails, - property, - basicValue, - typeBinding.getRootTable(), - bindingOptions, - bindingState, - bindingContext - ); - // force it to be non-nullable - column.setNullable( false ); - } - - public static void bindVersion( - AttributeMetadata attributeMetadata, - EntityTypeMetadata managedType, - RootClass typeBinding, - BindingOptions bindingOptions, - BindingState bindingState, - BindingContext bindingContext) { - final Property property = new Property(); - property.setName( attributeMetadata.getName() ); - typeBinding.setVersion( property ); - typeBinding.addProperty( property ); - - final BasicValue basicValue = new BasicValue( - bindingState.getMetadataBuildingContext(), - typeBinding.getRootTable() - ); - property.setValue( basicValue ); - - final MemberDetails memberDetails = attributeMetadata.getMember(); - bindImplicitJavaType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindJavaType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - bindJdbcType( memberDetails, property, basicValue, bindingOptions, bindingState, bindingContext ); - - final org.hibernate.mapping.Column column = processColumn( - memberDetails, - property, - basicValue, - typeBinding.getRootTable(), - bindingOptions, - bindingState, - bindingContext - ); - // force it to be non-nullable - column.setNullable( false ); - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/bind/tenancy/SimpleTenancyTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/bind/tenancy/SimpleTenancyTests.java index c866b76a47..fc1e040b8e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/bind/tenancy/SimpleTenancyTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/bind/tenancy/SimpleTenancyTests.java @@ -7,7 +7,7 @@ package org.hibernate.orm.test.boot.models.bind.tenancy; import org.hibernate.annotations.TenantId; -import org.hibernate.boot.models.bind.internal.binders.TenantIdBinder; +import org.hibernate.boot.models.bind.internal.BasicValueHelper; import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; @@ -38,7 +38,7 @@ public class SimpleTenancyTests { (context) -> { var metadataCollector = context.getMetadataCollector(); - assertThat( metadataCollector.getFilterDefinition( TenantIdBinder.FILTER_NAME ) ).isNotNull(); + assertThat( metadataCollector.getFilterDefinition( BasicValueHelper.TENANT_FILTER_NAME ) ).isNotNull(); final PersistentClass entityBinding = metadataCollector.getEntityBinding( ProtectedEntity.class.getName() ); final Property tenantProperty = entityBinding.getProperty( "tenant" ); @@ -65,7 +65,7 @@ public class SimpleTenancyTests { (context) -> { var metadataCollector = context.getMetadataCollector(); - assertThat( metadataCollector.getFilterDefinition( TenantIdBinder.FILTER_NAME ) ).isNotNull(); + assertThat( metadataCollector.getFilterDefinition( BasicValueHelper.TENANT_FILTER_NAME ) ).isNotNull(); final PersistentClass entityBinding = metadataCollector.getEntityBinding( ProtectedEntityWithColumn.class.getName() ); final Property tenantProperty = entityBinding.getProperty( "tenant" );