improvements to filter-related javadoc

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-06-12 13:12:55 +02:00
parent 52f9ce3c0e
commit 58e814965e
5 changed files with 64 additions and 27 deletions

View File

@ -13,12 +13,21 @@ import org.hibernate.annotations.FilterDef;
import jakarta.persistence.EntityNotFoundException;
/**
* Exception thrown if a filter would make a to-one association {@code null},
* which could lead to data loss.
* Even though filters are applied to load-by-key operations,
* a to-one association should never refer to an entity that is filtered.
* Thrown if an enabled {@linkplain FilterDef filter} would filter out
* the target of a {@link jakarta.persistence.ManyToOne @ManyToOne} or
* {@link jakarta.persistence.OneToOne @OneToOne} association.
* <p>
* By default, a filter does not apply to to-one association fetching,
* and this exception does not occur. However, if a filter is explicitly
* declared {@link FilterDef#applyToLoadByKey applyToLoadByKey = true},
* then the filter is applied, and it's possible that a filtered entity
* is the target of a to-one association belonging to an unfiltered entity.
* Replacing such a filtered object with {@code null} would lead to data
* loss, and so filtering never results in such replacement. Instead,
* this exception is thrown to indicate the inconsistency of the data
* with the filter definition.
*
* @see FilterDef#applyToLoadByKey()
* @see FilterDef#applyToLoadByKey
*/
public class EntityFilterException extends EntityNotFoundException {
private final String entityName;

View File

@ -8,18 +8,24 @@ package org.hibernate;
import java.util.Collection;
import org.hibernate.annotations.FilterDef;
import org.hibernate.engine.spi.FilterDefinition;
/**
* Allows control over an enabled filter at runtime. In particular, allows
* {@linkplain #setParameter(String, Object) arguments} to be assigned to
* parameters declared by the filter.
* Allows control over an enabled {@linkplain FilterDef filter} at runtime.
* In particular, allows {@linkplain #setParameter(String, Object) arguments}
* to be assigned to parameters declared by the filter.
* <p>
* A filter may be defined using {@link org.hibernate.annotations.FilterDef}
* and {@link org.hibernate.annotations.Filter}, and must be explicitly
* enabled at runtime by calling {@link Session#enableFilter(String)}.
* A filter may be defined using the annotations {@link FilterDef @FilterDef}
* and {@link org.hibernate.annotations.Filter @Filter}, but must be explicitly
* enabled at runtime by calling {@link Session#enableFilter(String)}, unless
* the filter is declared as {@linkplain FilterDef#autoEnabled auto-enabled}.
* If, in a given session, a filter not declared {@code autoEnabled = true} is
* not explicitly enabled by calling {@code enableFilter()}, the filter will
* have no effect in that session.
* <p>
* Every parameter of the filter must be set immediately after
* Every {@linkplain FilterDef#parameters parameter} of the filter must be
* supplied an argument by calling {@code setParameter()} immediately after
* {@code enableFilter()} is called, and before any other operation of the
* session is invoked.
*

View File

@ -17,7 +17,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Specifies that an entity or collection is affected by a named
* filter declared using {@link FilterDef}, and allows the
* filter declared using {@link FilterDef @FilterDef}, and allows the
* {@linkplain FilterDef#defaultCondition default filter condition}
* to be overridden for the annotated entity or collection role.
* <p>

View File

@ -49,12 +49,17 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* <p>
* At runtime, a filter may be enabled in a particular session by
* calling {@link org.hibernate.Session#enableFilter(String)},
* passing the name of the filter, and then setting its parameters.
* passing the name of the filter, and then supplying arguments to
* its parameters.
* <pre>
* session.enableFilter("Current");
* </pre>
* <p>
* A filter has no effect unless it is explicitly enabled.
* A filter has no effect unless:
* <ul>
* <li>it is explicitly enabled by calling {@code enableFilter}, or
* <li>it is declared {@link #autoEnabled autoEnabled = true}.
* </ul>
*
* @author Matthew Inger
* @author Emmanuel Bernard
@ -94,16 +99,31 @@ public @interface FilterDef {
ParamDef[] parameters() default {};
/**
* The flag used to auto-enable the filter on the session.
* Specifies that the filter auto-enabled, so that it is
* not necessary to call
* {@link org.hibernate.Session#enableFilter(String)}.
* <p>
* Arguments to {@linkplain #parameters} of auto-enabled
* filters are supplied via {@link ParamDef#resolver}.
*/
boolean autoEnabled() default false;
/**
* The flag used to decide if the filter will
* be applied on direct fetches or not.
* Specifies that the filter should be applied to operations
* which fetch an entity by its identifier.
* <p>
* If the flag is true, the filter will be
* applied on direct fetches, such as {@link org.hibernate.Session#find(Class, Object)}.
* By default, a filter does not apply to lookups by primary
* key, for example, when:
* <ul>
* <li>{@linkplain org.hibernate.FetchMode fetching} a
* {@code @ManyToOne} association, or
* <li>{@link org.hibernate.Session#find(Class, Object) find()}
* is called.
* </ul>
* <p>
* If the effect of a filter with {@code applyToLoadByKey = true}
* would be to nullify a to-one association,
* {@link org.hibernate.EntityFilterException} is thrown.
*/
@Incubating
boolean applyToLoadByKey() default false;

View File

@ -37,7 +37,7 @@ public @interface ParamDef {
* Generally deduced from the bind value. Allows to
* specify a specific type to use.
* <p>
* The supplied Class can be one of the following:<ul>
* The supplied {@link Class} may be one of the following:<ul>
* <li>
* a {@link org.hibernate.usertype.UserType}
* </li>
@ -48,19 +48,21 @@ public @interface ParamDef {
* a {@link org.hibernate.type.descriptor.java.JavaType}
* </li>
* <li>
* any Java type resolvable from {@link org.hibernate.type.descriptor.java.spi.JavaTypeRegistry}
* any Java type resolvable from
* {@link org.hibernate.type.descriptor.java.spi.JavaTypeRegistry}
* </li>
* </ul>
*/
Class<?> type();
/**
* The resolver to use when retrieving the parameter value.
* A class implementing {@link Supplier} which provides arguments
* to this parameter. This is especially useful in the case of
* {@linkplain FilterDef#autoEnabled auto-enabled} filters.
* <p>
* The parameter value can either be defined using the {@link org.hibernate.Filter setParameter}
* method or by providing a resolver, that will be executed to retrieve the value.
* <p>
* The supplied Class must implement {@link Supplier}
* When a resolver is specified for a filter parameter, it's not
* necessary to provide an argument for the parameter by calling
* {@link org.hibernate.Filter#setParameter(String, Object)}.
*/
Class<? extends Supplier> resolver() default Supplier.class;
}