HHH-17460 - Ongoing JPA 32 work
Support for auto-enabled filters (HHH-14968)
This commit is contained in:
parent
2d066d1ae5
commit
d10d990c5b
|
@ -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()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue