HHH-17460 - Ongoing JPA 32 work

Support for auto-enabled filters (HHH-14968)
This commit is contained in:
Steve Ebersole 2024-03-20 20:59:53 -05:00
parent 2d066d1ae5
commit d10d990c5b
11 changed files with 223 additions and 153 deletions

View File

@ -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<TenantId> {
new FilterDefinition(
FILTER_NAME,
"",
singletonMap( PARAMETER_NAME, tenantIdType ),
Collections.emptyMap(),
false,
true
true,
singletonMap( PARAMETER_NAME, tenantIdType ),
Collections.emptyMap()
)
);
}

View File

@ -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> filterDef = annotatedElement.getAnnotationUsage( FilterDef.class );
final AnnotationUsage<FilterDefs> filterDefs = getOverridableAnnotation( annotatedElement, FilterDefs.class, context );
if ( filterDef != null ) {
bindFilterDef( filterDef, context );
}
if ( filterDefs != null ) {
final List<AnnotationUsage<FilterDef>> nestedDefs = filterDefs.getList( "value" );
for ( AnnotationUsage<FilterDef> def : nestedDefs ) {
bindFilterDef( def, context );
}
}
annotatedElement.forEachAnnotationUsage( FilterDef.class, (usage) -> {
bindFilterDef( usage, context );
} );
}
public static void bindFilterDef(AnnotationUsage<FilterDef> 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<? extends Supplier<?>> resolveParamResolver(ParamDef paramDef, MetadataBuildingContext context) {
final Class<? extends Supplier> clazz = paramDef.resolver();
@SuppressWarnings("rawtypes")
private static ManagedBean<? extends Supplier> resolveParamResolver(ClassDetails resolverClassDetails, MetadataBuildingContext context) {
final Class<? extends Supplier> clazz = resolverClassDetails.toJavaClass();
assert clazz != Supplier.class;
final BootstrapContext bootstrapContext = context.getBootstrapContext();
return (ManagedBean<? extends Supplier<?>>)
@ -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<UserType<?>>) type, context );
}

View File

@ -184,48 +184,10 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
public void processFilterDefinitions() {
final Map<String, FilterDefRegistration> filterDefRegistrations = domainModelSource.getGlobalRegistrations().getFilterDefRegistrations();
for ( Map.Entry<String, FilterDefRegistration> filterDefRegistrationEntry : filterDefRegistrations.entrySet() ) {
final Map<String, JdbcMapping> parameterJdbcMappings = new HashMap<>();
final Map<String, ClassDetails> parameterDefinitions = filterDefRegistrationEntry.getValue().getParameters();
if ( CollectionHelper.isNotEmpty( parameterDefinitions ) ) {
for ( Map.Entry<String, ClassDetails> 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<UserType<?>> impl = classDetails.toJavaClass();
return resolveUserType( impl, context );
}
if ( classDetails.isImplementor( AttributeConverter.class ) ) {
final Class<AttributeConverter<?,?>> impl = classDetails.toJavaClass();
return resolveAttributeConverter( impl, context );
}
if ( classDetails.isImplementor( JavaType.class ) ) {
final Class<JavaType<?>> impl = classDetails.toJavaClass();
return resolveJavaType( impl, context );
}
return resolveBasicType( classDetails.toJavaClass(), context );
}
@Override

View File

@ -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<String, JdbcMapping> extractParameterMap(FilterDefRegistration registration) {
final Map<String, ClassDetails> parameters = registration.getParameters();
if ( CollectionHelper.isEmpty( parameters ) ) {
return Collections.emptyMap();
}
final TypeConfiguration typeConfiguration = metadataBuildingContext.getBootstrapContext().getTypeConfiguration();
final Map<String, JdbcMapping> result = new HashMap<>();
parameters.forEach( (name, typeDetails) -> {
result.put( name, typeConfiguration.getBasicTypeForJavaType( typeDetails.toJavaClass() ) );
} );
return result;
metadataBuildingContext.getMetadataCollector().addFilterDefinition( registration.toFilterDefinition( metadataBuildingContext ) );
}
}

View File

@ -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<String, ClassDetails> paramJdbcMappings;
final Map<String, ClassDetails> parameterResolvers;
final List<AnnotationUsage<ParamDef>> parameters = usage.getList( "parameters" );
if ( CollectionHelper.isEmpty( parameters ) ) {
paramJdbcMappings = emptyMap();
parameterResolvers = emptyMap();
}
else {
paramJdbcMappings = new HashMap<>();
parameterResolvers = new HashMap<>();
for ( AnnotationUsage<ParamDef> 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<String, ClassDetails> extractFilterParameters(AnnotationUsage<FilterDef> 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<String, ClassDetails> paramJdbcMappings;
final Map<String, ClassDetails> parameterResolvers;
final List<JaxbFilterDefImpl.JaxbFilterParamImpl> jaxbParameters = filterDefinition.getFilterParams();
if ( jaxbParameters.isEmpty() ) {
paramJdbcMappings = emptyMap();
parameterResolvers = emptyMap();
}
else {
paramJdbcMappings = new HashMap<>();
parameterResolvers = new HashMap<>();
private Map<String, ClassDetails> extractFilterParameters(JaxbFilterDefImpl source) {
final List<JaxbFilterDefImpl.JaxbFilterParamImpl> 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<String, ClassDetails> 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<String, ClassDetails> parameters) {
public void collectFilterDefinition(
String name,
String defaultCondition,
boolean autoEnabled,
Map<String, ClassDetails> parameterTypes,
Map<String, ClassDetails> 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<QueryHint> 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<QueryHint> 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<QueryHint> 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<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_COMMENT );
hint.setAttributeValue( "value", jaxbNamedQuery.getComment() );

View File

@ -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<String, ClassDetails> parameters;
private final Map<String, ClassDetails> parameterTypes;
private final Map<String, ClassDetails> parameterResolvers;
public FilterDefRegistration(String name, String defaultCondition, Map<String, ClassDetails> parameters) {
public FilterDefRegistration(
String name,
String defaultCondition,
boolean autoEnabled,
Map<String, ClassDetails> parameterTypes,
Map<String, ClassDetails> 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<String, ClassDetails> getParameters() {
return parameters;
public boolean isAutoEnabled() {
return autoEnabled;
}
public Map<String, ClassDetails> getParameterTypes() {
return parameterTypes;
}
public Map<String, ClassDetails> getParameterResolvers() {
return parameterResolvers;
}
public FilterDefinition toFilterDefinition(MetadataBuildingContext buildingContext) {
final ManagedBeanRegistry beanRegistry = buildingContext
.getBootstrapContext()
.getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final Map<String, JdbcMapping> 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<String, ManagedBean<? extends Supplier>> 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
);
}
}

View File

@ -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() {

View File

@ -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<String, JdbcMapping> explicitParamJaMappings) {
this( name, defaultCondition, explicitParamJaMappings, Collections.emptyMap(), false, false);
public FilterDefinition(String name, String defaultCondition, @Nullable Map<String, JdbcMapping> explicitParamJaMappings) {
this( name, defaultCondition, false, false, explicitParamJaMappings, Collections.emptyMap() );
}
public FilterDefinition(
String name,
String defaultCondition,
@Nullable Map<String, JdbcMapping> explicitParamJaMappings,
Map<String, ManagedBean<? extends Supplier<?>>> parameterResolverMap,
boolean autoEnabled,
boolean applyToLoadByKey) {
boolean applyToLoadByKey,
@Nullable Map<String, JdbcMapping> explicitParamJaMappings,
@Nullable Map<String, ManagedBean<? extends Supplier<?>>> parameterResolverMap) {
this.filterName = name;
this.defaultFilterCondition = defaultCondition;
if ( explicitParamJaMappings != null ) {

View File

@ -139,8 +139,7 @@
<!-- hbm: auxiliary database object definitions -->
<xsd:element name="database-object" minOccurs="0" maxOccurs="unbounded" type="orm:database-object"/>
</xsd:sequence>
<xsd:attribute name="version" type="orm:versionType"
fixed="3.2" use="required"/>
<xsd:attribute name="version" type="orm:supportedVersionType" fixed="7.0" use="required"/>
</xsd:complexType>
</xsd:element>
@ -152,6 +151,22 @@
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="supportedVersionType">
<xsd:restriction base="orm:versionType">
<!-- JPA versions -->
<xsd:enumeration value="1.0" />
<xsd:enumeration value="2.0" />
<xsd:enumeration value="2.1" />
<xsd:enumeration value="2.2" />
<xsd:enumeration value="3.0" />
<xsd:enumeration value="3.1" />
<xsd:enumeration value="3.2" />
<!-- Hibernate versions -->
<xsd:enumeration value="7.0" />
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
@ -2738,6 +2753,13 @@
<xsd:documentation>
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;
}
</xsd:documentation>
</xsd:annotation>
@ -2748,15 +2770,25 @@
<xsd:annotation>
<xsd:documentation>
Used to identify all bind parameters in the condition element
<![CDATA[
@interface ParamDef {
String name();
Class<?> type();
Class<? extends Supplier> resolver() default Supplier.class;
}
]]>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" use="required" type="xsd:string"/>
<xsd:attribute name="resolver" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="auto-enabled" type="xsd:boolean" default="false"/>
</xsd:complexType>
<xsd:complexType name="hbm-filter">

View File

@ -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<String, ClassDetails> parameters = nameFilter.getParameters();
final Map<String, ClassDetails> parameters = nameFilter.getParameterTypes();
assertThat( parameters ).hasSize( 1 );
assertThat( parameters ).containsKey( "name" );
assertThat( parameters.get( "name" ).getName() ).isEqualTo( String.class.getName() );

View File

@ -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() );
}
}