From d10d990c5bcbf5082efbb6e7b85b95c5c066827f Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 20 Mar 2024 20:59:53 -0500 Subject: [PATCH] HHH-17460 - Ongoing JPA 32 work Support for auto-enabled filters (HHH-14968) --- .../binder/internal/TenantIdBinder.java | 7 +- .../boot/model/internal/FilterDefBinder.java | 41 +++---- ...AnnotationMetadataSourceProcessorImpl.java | 44 +------ .../bind/internal/BindingStateImpl.java | 25 +--- .../internal/GlobalRegistrationsImpl.java | 114 ++++++++++++------ .../categorize/spi/FilterDefRegistration.java | 80 ++++++++++-- .../hibernate/boot/xsd/MappingXsdSupport.java | 6 +- .../engine/spi/FilterDefinition.java | 13 +- .../org/hibernate/xsd/mapping/mapping-7.0.xsd | 36 +++++- .../models/process/SimpleProcessorTests.java | 2 +- .../models/xml/XmlProcessingSmokeTests.java | 8 +- 11 files changed, 223 insertions(+), 153 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java b/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java index c0de6cb02b..8d3b49d56f 100644 --- a/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java @@ -7,7 +7,6 @@ package org.hibernate.binder.internal; import java.util.Collections; -import java.util.function.Supplier; import org.hibernate.MappingException; import org.hibernate.annotations.TenantId; @@ -57,10 +56,10 @@ public class TenantIdBinder implements AttributeBinder { new FilterDefinition( FILTER_NAME, "", - singletonMap( PARAMETER_NAME, tenantIdType ), - Collections.emptyMap(), false, - true + true, + singletonMap( PARAMETER_NAME, tenantIdType ), + Collections.emptyMap() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FilterDefBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FilterDefBinder.java index ad23bea3b5..fadec19772 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FilterDefBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FilterDefBinder.java @@ -10,11 +10,11 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.function.Supplier; import org.hibernate.AnnotationException; import org.hibernate.MappingException; import org.hibernate.annotations.FilterDef; -import org.hibernate.annotations.FilterDefs; import org.hibernate.annotations.ParamDef; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.engine.spi.FilterDefinition; @@ -23,38 +23,30 @@ import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.models.spi.AnnotationTarget; import org.hibernate.models.spi.AnnotationUsage; import org.hibernate.models.spi.ClassDetails; +import org.hibernate.resource.beans.spi.ManagedBean; +import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.usertype.UserType; import jakarta.persistence.AttributeConverter; -import java.util.function.Supplier; import static java.util.Collections.emptyMap; import static org.hibernate.boot.model.internal.AnnotationHelper.resolveAttributeConverter; import static org.hibernate.boot.model.internal.AnnotationHelper.resolveBasicType; import static org.hibernate.boot.model.internal.AnnotationHelper.resolveJavaType; import static org.hibernate.boot.model.internal.AnnotationHelper.resolveUserType; -import static org.hibernate.boot.model.internal.BinderHelper.getOverridableAnnotation; import static org.hibernate.internal.CoreLogging.messageLogger; /** * @author Gavin King */ -class FilterDefBinder { +public class FilterDefBinder { private static final CoreMessageLogger LOG = messageLogger( FilterDefBinder.class ); public static void bindFilterDefs(AnnotationTarget annotatedElement, MetadataBuildingContext context) { - final AnnotationUsage filterDef = annotatedElement.getAnnotationUsage( FilterDef.class ); - final AnnotationUsage filterDefs = getOverridableAnnotation( annotatedElement, FilterDefs.class, context ); - if ( filterDef != null ) { - bindFilterDef( filterDef, context ); - } - if ( filterDefs != null ) { - final List> nestedDefs = filterDefs.getList( "value" ); - for ( AnnotationUsage def : nestedDefs ) { - bindFilterDef( def, context ); - } - } + annotatedElement.forEachAnnotationUsage( FilterDef.class, (usage) -> { + bindFilterDef( usage, context ); + } ); } public static void bindFilterDef(AnnotationUsage filterDef, MetadataBuildingContext context) { @@ -89,8 +81,9 @@ class FilterDefBinder { } paramJdbcMappings.put( parameterName, jdbcMapping ); - if ( paramDef.resolver() != Supplier.class ) { - parameterResolvers.put( paramDef.name(), resolveParamResolver( paramDef, context ) ); + final ClassDetails resolverClassDetails = explicitParameter.getClassDetails( "resolver" ); + if ( !resolverClassDetails.getName().equals( Supplier.class.getName() ) ) { + parameterResolvers.put( explicitParameter.getString( "name" ), resolveParamResolver( resolverClassDetails, context ) ); } } } @@ -98,19 +91,19 @@ class FilterDefBinder { final FilterDefinition filterDefinition = new FilterDefinition( name, filterDef.getString( "defaultCondition" ), - paramJdbcMappings, - parameterResolvers, filterDef.getBoolean( "autoEnabled" ), - filterDef.applyToLoadByKey() + filterDef.applyToLoadByKey(), + paramJdbcMappings, + parameterResolvers ); LOG.debugf( "Binding filter definition: %s", filterDefinition.getFilterName() ); context.getMetadataCollector().addFilterDefinition( filterDefinition ); } - @SuppressWarnings({"rawtypes", "unchecked"}) - private static ManagedBean> resolveParamResolver(ParamDef paramDef, MetadataBuildingContext context) { - final Class clazz = paramDef.resolver(); + @SuppressWarnings("rawtypes") + private static ManagedBean resolveParamResolver(ClassDetails resolverClassDetails, MetadataBuildingContext context) { + final Class clazz = resolverClassDetails.toJavaClass(); assert clazz != Supplier.class; final BootstrapContext bootstrapContext = context.getBootstrapContext(); return (ManagedBean>) @@ -120,7 +113,7 @@ class FilterDefBinder { } @SuppressWarnings("unchecked") - private static JdbcMapping resolveFilterParamType(Class type, MetadataBuildingContext context) { + public static JdbcMapping resolveFilterParamType(Class type, MetadataBuildingContext context) { if ( UserType.class.isAssignableFrom( type ) ) { return resolveUserType( (Class>) type, context ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java index a3c131304d..29e59d2945 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java @@ -184,48 +184,10 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc public void processFilterDefinitions() { final Map filterDefRegistrations = domainModelSource.getGlobalRegistrations().getFilterDefRegistrations(); for ( Map.Entry filterDefRegistrationEntry : filterDefRegistrations.entrySet() ) { - final Map parameterJdbcMappings = new HashMap<>(); - final Map parameterDefinitions = filterDefRegistrationEntry.getValue().getParameters(); - if ( CollectionHelper.isNotEmpty( parameterDefinitions ) ) { - for ( Map.Entry parameterEntry : parameterDefinitions.entrySet() ) { - final String parameterClassName = parameterEntry.getValue().getClassName(); - final ClassDetails parameterClassDetails = domainModelSource.getClassDetailsRegistry().resolveClassDetails( parameterClassName ); - parameterJdbcMappings.put( - parameterEntry.getKey(), - resolveFilterParamType( parameterClassDetails, rootMetadataBuildingContext ) - ); - } - } - - rootMetadataBuildingContext.getMetadataCollector().addFilterDefinition( new FilterDefinition( - filterDefRegistrationEntry.getValue().getName(), - filterDefRegistrationEntry.getValue().getDefaultCondition(), - parameterJdbcMappings - ) ); + final FilterDefRegistration filterDefRegistration = filterDefRegistrationEntry.getValue(); + final FilterDefinition filterDefinition = filterDefRegistration.toFilterDefinition( rootMetadataBuildingContext ); + rootMetadataBuildingContext.getMetadataCollector().addFilterDefinition( filterDefinition ); } - - } - - private static JdbcMapping resolveFilterParamType( - ClassDetails classDetails, - MetadataBuildingContext context) { - if ( classDetails.isImplementor( UserType.class ) ) { - final Class> impl = classDetails.toJavaClass(); - return resolveUserType( impl, context ); - - } - - if ( classDetails.isImplementor( AttributeConverter.class ) ) { - final Class> impl = classDetails.toJavaClass(); - return resolveAttributeConverter( impl, context ); - } - - if ( classDetails.isImplementor( JavaType.class ) ) { - final Class> impl = classDetails.toJavaClass(); - return resolveJavaType( impl, context ); - } - - return resolveBasicType( classDetails.toJavaClass(), context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BindingStateImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BindingStateImpl.java index 29c4dfedde..d67d65d5f1 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BindingStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/bind/internal/BindingStateImpl.java @@ -6,7 +6,6 @@ */ package org.hibernate.boot.models.bind.internal; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; @@ -21,12 +20,8 @@ import org.hibernate.boot.models.categorize.spi.ManagedTypeMetadata; import org.hibernate.boot.models.categorize.spi.TableOwner; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.internal.util.KeyedConsumer; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.models.spi.ClassDetails; -import org.hibernate.type.spi.TypeConfiguration; /** * @author Steve Ebersole @@ -172,24 +167,6 @@ public class BindingStateImpl implements BindingState { @Override public void apply(FilterDefRegistration registration) { - metadataBuildingContext.getMetadataCollector().addFilterDefinition( new FilterDefinition( - registration.getName(), - registration.getDefaultCondition(), - extractParameterMap( registration ) - ) ); - } - - private Map extractParameterMap(FilterDefRegistration registration) { - final Map parameters = registration.getParameters(); - if ( CollectionHelper.isEmpty( parameters ) ) { - return Collections.emptyMap(); - } - - final TypeConfiguration typeConfiguration = metadataBuildingContext.getBootstrapContext().getTypeConfiguration(); - final Map result = new HashMap<>(); - parameters.forEach( (name, typeDetails) -> { - result.put( name, typeConfiguration.getBasicTypeForJavaType( typeDetails.toJavaClass() ) ); - } ); - return result; + metadataBuildingContext.getMetadataCollector().addFilterDefinition( registration.toFilterDefinition( metadataBuildingContext ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java index a136bcece0..0fa8c03a99 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Supplier; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.GenericGenerator; @@ -106,6 +107,7 @@ import static org.hibernate.boot.models.HibernateAnnotations.JDBC_TYPE_REG; import static org.hibernate.boot.models.HibernateAnnotations.TYPE_REG; import static org.hibernate.boot.models.internal.AnnotationUsageHelper.applyAttributeIfSpecified; import static org.hibernate.boot.models.internal.AnnotationUsageHelper.applyStringAttributeIfSpecified; +import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; @@ -314,7 +316,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { registrations.forEach( (registration) -> { final ClassDetails explicitDomainType; final String explicitDomainTypeName = registration.getClazz(); - if ( StringHelper.isNotEmpty( explicitDomainTypeName ) ) { + if ( isNotEmpty( explicitDomainTypeName ) ) { explicitDomainType = sourceModelContext.getClassDetailsRegistry().resolveClassDetails( explicitDomainTypeName ); } else { @@ -483,11 +485,35 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { // Filter-defs public void collectFilterDefinitions(AnnotationTarget annotationTarget) { - annotationTarget.forEachAnnotationUsage( FILTER_DEF, (usage) -> collectFilterDefinition( - usage.getAttributeValue( "name" ), - usage.getAttributeValue( "defaultCondition" ), - extractFilterParameters( usage ) - ) ); + annotationTarget.forEachAnnotationUsage( FILTER_DEF, (usage) -> { + final Map paramJdbcMappings; + final Map parameterResolvers; + final List> parameters = usage.getList( "parameters" ); + if ( CollectionHelper.isEmpty( parameters ) ) { + paramJdbcMappings = emptyMap(); + parameterResolvers = emptyMap(); + } + else { + paramJdbcMappings = new HashMap<>(); + parameterResolvers = new HashMap<>(); + + for ( AnnotationUsage parameter : parameters ) { + paramJdbcMappings.put( parameter.getString( "name" ), parameter.getClassDetails( "type" ) ); + final ClassDetails resolverClassDetails = parameter.getClassDetails( "resolver" ); + if ( !resolverClassDetails.getName().equals( Supplier.class.getName() ) ) { + parameterResolvers.put( parameter.getString( "name" ), resolverClassDetails ); + } + } + } + + collectFilterDefinition( + usage.getString( "name" ), + usage.getString( "defaultCondition" ), + usage.getBoolean( "autoEnabled" ), + paramJdbcMappings, + parameterResolvers + ); + } ); } private Map extractFilterParameters(AnnotationUsage source) { @@ -508,40 +534,58 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { return; } - filterDefinitions.forEach( (filterDefinition) -> collectFilterDefinition( - filterDefinition.getName(), - filterDefinition.getDefaultCondition(), - extractFilterParameters( filterDefinition ) - ) ); - } + filterDefinitions.forEach( (filterDefinition) -> { + final Map paramJdbcMappings; + final Map parameterResolvers; + final List jaxbParameters = filterDefinition.getFilterParams(); + if ( jaxbParameters.isEmpty() ) { + paramJdbcMappings = emptyMap(); + parameterResolvers = emptyMap(); + } + else { + paramJdbcMappings = new HashMap<>(); + parameterResolvers = new HashMap<>(); - private Map extractFilterParameters(JaxbFilterDefImpl source) { - final List parameters = source.getFilterParams(); - if ( isEmpty( parameters ) ) { - return null; - } + for ( JaxbFilterDefImpl.JaxbFilterParamImpl jaxbParameter : jaxbParameters ) { + final ClassDetails targetClassDetails = XmlAnnotationHelper.resolveJavaType( + jaxbParameter.getType(), + sourceModelContext.getClassDetailsRegistry() + ); + paramJdbcMappings.put( jaxbParameter.getName(), targetClassDetails ); - final Map result = new HashMap<>( parameters.size() ); - for ( JaxbFilterDefImpl.JaxbFilterParamImpl parameter : parameters ) { - // for now, don't check whether nothing was specified; this situation - // should resolve to Object - let's see how that reacts - final ClassDetails targetClassDetails = XmlAnnotationHelper.resolveJavaType( - parameter.getType(), - sourceModelContext.getClassDetailsRegistry() + if ( isNotEmpty( jaxbParameter.getResolver() ) ) { + final ClassDetails resolverClassDetails = XmlAnnotationHelper.resolveJavaType( + jaxbParameter.getType(), + sourceModelContext.getClassDetailsRegistry() + ); + parameterResolvers.put( jaxbParameter.getName(), resolverClassDetails ); + } + } + } + + collectFilterDefinition( + filterDefinition.getName(), + filterDefinition.getDefaultCondition(), + filterDefinition.isAutoEnabled(), + paramJdbcMappings, + parameterResolvers ); - result.put( parameter.getName(), targetClassDetails ); - } - return result; + } ); } - public void collectFilterDefinition(String name, String defaultCondition, Map parameters) { + public void collectFilterDefinition( + String name, + String defaultCondition, + boolean autoEnabled, + Map parameterTypes, + Map parameterResolvers) { if ( filterDefRegistrations == null ) { filterDefRegistrations = new HashMap<>(); } final FilterDefRegistration previousEntry = filterDefRegistrations.put( name, - new FilterDefRegistration( name, defaultCondition, parameters ) + new FilterDefRegistration( name, defaultCondition, autoEnabled, parameterTypes, parameterResolvers ) ); if ( previousEntry != null ) { // legacy code simply allows the collision overwriting the previous @@ -558,7 +602,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { } final String explicitRename = importedUsage.getString( "rename" ); - final String rename = StringHelper.isNotEmpty( explicitRename ) + final String rename = isNotEmpty( explicitRename ) ? explicitRename : StringHelper.unqualify( classDetails.getName() ); @@ -915,14 +959,14 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { hint.setAttributeValue( "value", jaxbNamedQuery.getCacheMode().name() ); } - if ( StringHelper.isNotEmpty( jaxbNamedQuery.getCacheRegion() ) ) { + if ( isNotEmpty( jaxbNamedQuery.getCacheRegion() ) ) { final MutableAnnotationUsage hint = makeAnnotation( JpaAnnotations.QUERY_HINT ); hint.setAttributeValue( "name", AvailableHints.HINT_CACHE_REGION ); hint.setAttributeValue( "value", jaxbNamedQuery.getCacheRegion() ); } } - if ( StringHelper.isNotEmpty( jaxbNamedQuery.getComment() ) ) { + if ( isNotEmpty( jaxbNamedQuery.getComment() ) ) { final MutableAnnotationUsage hint = makeAnnotation( JpaAnnotations.QUERY_HINT ); hint.setAttributeValue( "name", AvailableHints.HINT_COMMENT ); hint.setAttributeValue( "value", jaxbNamedQuery.getComment() ); @@ -967,7 +1011,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { queryAnnotation.setAttributeValue( "name", jaxbNamedQuery.getName() ); queryAnnotation.setAttributeValue( "query", jaxbNamedQuery.getQuery() ); - if ( StringHelper.isNotEmpty( jaxbNamedQuery.getResultClass() ) ) { + if ( isNotEmpty( jaxbNamedQuery.getResultClass() ) ) { queryAnnotation.setAttributeValue( "resultClass", sourceModelContext.getClassDetailsRegistry().resolveClassDetails( jaxbNamedQuery.getResultClass() ) ); } @@ -1002,7 +1046,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { hint.setAttributeValue( "value", jaxbNamedQuery.getCacheMode().name() ); } - if ( StringHelper.isNotEmpty( jaxbNamedQuery.getCacheRegion() ) ) { + if ( isNotEmpty( jaxbNamedQuery.getCacheRegion() ) ) { final MutableAnnotationUsage hint = makeAnnotation( JpaAnnotations.QUERY_HINT ); hint.setAttributeValue( "name", AvailableHints.HINT_CACHE_REGION ); hint.setAttributeValue( "value", jaxbNamedQuery.getCacheRegion() ); @@ -1015,7 +1059,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { hint.setAttributeValue( "value", Boolean.TRUE.toString() ); } - if ( StringHelper.isNotEmpty( jaxbNamedQuery.getComment() ) ) { + if ( isNotEmpty( jaxbNamedQuery.getComment() ) ) { final MutableAnnotationUsage hint = makeAnnotation( JpaAnnotations.QUERY_HINT ); hint.setAttributeValue( "name", AvailableHints.HINT_COMMENT ); hint.setAttributeValue( "value", jaxbNamedQuery.getComment() ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/FilterDefRegistration.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/FilterDefRegistration.java index 0e358adb1d..5624124b62 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/FilterDefRegistration.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/FilterDefRegistration.java @@ -6,29 +6,47 @@ */ package org.hibernate.boot.models.categorize.spi; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import java.util.function.Supplier; +import org.hibernate.boot.model.internal.FilterDefBinder; +import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.engine.spi.FilterDefinition; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.models.spi.ClassDetails; +import org.hibernate.resource.beans.spi.ManagedBean; +import org.hibernate.resource.beans.spi.ManagedBeanRegistry; /** * Global registration of a filter definition * * @see org.hibernate.annotations.FilterDef - * @see org.hibernate.boot.jaxb.mapping.JaxbFilterDef + * @see org.hibernate.boot.jaxb.mapping.spi.JaxbFilterDefImpl * * @author Marco Belladelli */ public class FilterDefRegistration { private final String name; - private final String defaultCondition; + private final boolean autoEnabled; - private final Map parameters; + private final Map parameterTypes; + private final Map parameterResolvers; - public FilterDefRegistration(String name, String defaultCondition, Map parameters) { + public FilterDefRegistration( + String name, + String defaultCondition, + boolean autoEnabled, + Map parameterTypes, + Map parameterResolvers) { this.name = name; this.defaultCondition = defaultCondition; - this.parameters = parameters; + this.autoEnabled = autoEnabled; + this.parameterTypes = parameterTypes; + this.parameterResolvers = parameterResolvers; } public String getName() { @@ -39,7 +57,55 @@ public class FilterDefRegistration { return defaultCondition; } - public Map getParameters() { - return parameters; + public boolean isAutoEnabled() { + return autoEnabled; + } + + public Map getParameterTypes() { + return parameterTypes; + } + + public Map getParameterResolvers() { + return parameterResolvers; + } + + public FilterDefinition toFilterDefinition(MetadataBuildingContext buildingContext) { + final ManagedBeanRegistry beanRegistry = buildingContext + .getBootstrapContext() + .getServiceRegistry() + .getService( ManagedBeanRegistry.class ); + + final Map parameterJdbcMappings; + if ( CollectionHelper.isEmpty( parameterTypes ) ) { + parameterJdbcMappings = Collections.emptyMap(); + } + else { + parameterJdbcMappings = new HashMap<>(); + parameterTypes.forEach( (key,value) -> { + parameterJdbcMappings.put( + key, + FilterDefBinder.resolveFilterParamType( value.toJavaClass(), buildingContext ) + ); + } ); + } + + final Map> parameterResolvers; + if ( CollectionHelper.isEmpty( this.parameterResolvers ) ) { + parameterResolvers = Collections.emptyMap(); + } + else { + parameterResolvers = new HashMap<>(); + this.parameterResolvers.forEach( (key,value) -> { + parameterResolvers.put( key, beanRegistry.getBean( value.toJavaClass() ) ); + } ); + } + + return new FilterDefinition( + getName(), + getDefaultCondition(), + isAutoEnabled(), + parameterJdbcMappings, + parameterResolvers + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java b/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java index b05bbf06a0..02563969e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java @@ -29,9 +29,9 @@ public class MappingXsdSupport { "http://www.hibernate.org/xsd/orm/mapping" ); - public static final XsdDescriptor _320 = LocalXsdResolver.buildXsdDescriptor( + public static final XsdDescriptor _70 = LocalXsdResolver.buildXsdDescriptor( "org/hibernate/xsd/mapping/mapping-7.0.xsd", - "3.2", + "7.0", "http://www.hibernate.org/xsd/orm/mapping" ); @@ -94,7 +94,7 @@ public class MappingXsdSupport { } public static XsdDescriptor latestDescriptor() { - return _320; + return _70; } public static XsdDescriptor latestJpaDescriptor() { diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/FilterDefinition.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/FilterDefinition.java index 7f2b0f49c9..26046dd0d7 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/FilterDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/FilterDefinition.java @@ -44,20 +44,17 @@ public class FilterDefinition implements Serializable { * * @param name The name of the filter for which this configuration is in effect. */ - public FilterDefinition( - String name, - String defaultCondition, - @Nullable Map explicitParamJaMappings) { - this( name, defaultCondition, explicitParamJaMappings, Collections.emptyMap(), false, false); + public FilterDefinition(String name, String defaultCondition, @Nullable Map explicitParamJaMappings) { + this( name, defaultCondition, false, false, explicitParamJaMappings, Collections.emptyMap() ); } public FilterDefinition( String name, String defaultCondition, - @Nullable Map explicitParamJaMappings, - Map>> parameterResolverMap, boolean autoEnabled, - boolean applyToLoadByKey) { + boolean applyToLoadByKey, + @Nullable Map explicitParamJaMappings, + @Nullable Map>> parameterResolverMap) { this.filterName = name; this.defaultFilterCondition = defaultCondition; if ( explicitParamJaMappings != null ) { diff --git a/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd b/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd index fdde1170af..c7c0d9b2e1 100644 --- a/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd +++ b/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd @@ -139,8 +139,7 @@ - + @@ -152,6 +151,22 @@ + + + + + + + + + + + + + + + + @@ -2738,6 +2753,13 @@ Specifies a filter definition. After definition, a filter can be applied to entity or collection by name. + + @interface FilterDef { + String name(); + String defaultCondition() default ""; + ParamDef[] parameters() default {}; + boolean autoEnabled() default false; + } @@ -2748,15 +2770,25 @@ Used to identify all bind parameters in the condition element + + type(); + Class resolver() default Supplier.class; + } + ]]> + + diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/process/SimpleProcessorTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/process/SimpleProcessorTests.java index 29e256e121..1a6e4d6939 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/process/SimpleProcessorTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/process/SimpleProcessorTests.java @@ -140,7 +140,7 @@ public class SimpleProcessorTests { assertThat( filterDefRegistrations ).containsKey( "name_filter" ); final FilterDefRegistration nameFilter = filterDefRegistrations.get( "name_filter" ); assertThat( nameFilter.getDefaultCondition() ).isEqualTo( "name = :name" ); - final Map parameters = nameFilter.getParameters(); + final Map parameters = nameFilter.getParameterTypes(); assertThat( parameters ).hasSize( 1 ); assertThat( parameters ).containsKey( "name" ); assertThat( parameters.get( "name" ).getName() ).isEqualTo( String.class.getName() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/XmlProcessingSmokeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/XmlProcessingSmokeTests.java index e7a1633e17..9e54faeb94 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/XmlProcessingSmokeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/XmlProcessingSmokeTests.java @@ -157,14 +157,14 @@ public class XmlProcessingSmokeTests { final FilterDefRegistration amountFilter = filterDefRegistrations.get( "amount_filter" ); assertThat( amountFilter.getDefaultCondition() ).isEqualTo( "amount = :amount" ); - assertThat( amountFilter.getParameters() ).hasSize( 1 ); - final ClassDetails amountParameterType = amountFilter.getParameters().get( "amount" ); + assertThat( amountFilter.getParameterTypes() ).hasSize( 1 ); + final ClassDetails amountParameterType = amountFilter.getParameterTypes().get( "amount" ); assertThat( amountParameterType.getClassName() ).isEqualTo( int.class.getName() ); final FilterDefRegistration nameFilter = filterDefRegistrations.get( "name_filter" ); assertThat( nameFilter.getDefaultCondition() ).isEqualTo( "name = :name" ); - assertThat( nameFilter.getParameters() ).hasSize( 1 ); - final ClassDetails nameParameterType = nameFilter.getParameters().get( "name" ); + assertThat( nameFilter.getParameterTypes() ).hasSize( 1 ); + final ClassDetails nameParameterType = nameFilter.getParameterTypes().get( "name" ); assertThat( nameParameterType.getClassName() ).isEqualTo( String.class.getName() ); } }