improve javadoc for annotations related to filters + discriminators

Also:

- deprecate a layer-breaking method of org.hibernate.Filter
  (consistent with what we already did on SessionFactory)
- fix the incorrect @Target of @SqlFragmentAlias
- add some missing @since annotations
- add cross-links to DialectOverride
This commit is contained in:
Gavin 2022-11-18 12:20:26 +01:00 committed by Gavin King
parent d25c1a44f0
commit c51604c6b7
30 changed files with 258 additions and 46 deletions

View File

@ -32,8 +32,6 @@ import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
/**
* @author Vlad Mihalcea

View File

@ -35,14 +35,18 @@ public interface Filter {
String getName();
/**
* Get the associated {@link FilterDefinition definition} of
* this named filter.
* Get the associated {@link FilterDefinition definition} of this
* named filter.
*
* @return The filter definition
*
* @deprecated There is no plan to remove this operation, but its use
* should be avoided since {@link FilterDefinition} is an
* SPI type, and so this operation is a layer-breaker.
*/
@Deprecated
FilterDefinition getFilterDefinition();
/**
* Set the named parameter's value for this filter.
*

View File

@ -17,6 +17,7 @@ package org.hibernate;
*
* @see jakarta.persistence.Column#length()
*
* @since 6.0
* @author Gavin King
*/
public final class Length {

View File

@ -209,6 +209,8 @@ public interface Session extends SharedSessionContract, EntityManager {
* The JPA-defined {@link CacheStoreMode}.
*
* @see #getCacheMode()
*
* @since 6.2
*/
CacheStoreMode getCacheStoreMode();
@ -216,6 +218,8 @@ public interface Session extends SharedSessionContract, EntityManager {
* The JPA-defined {@link CacheRetrieveMode}.
*
* @see #getCacheMode()
*
* @since 6.2
*/
CacheRetrieveMode getCacheRetrieveMode();
@ -225,6 +229,8 @@ public interface Session extends SharedSessionContract, EntityManager {
* @param cacheStoreMode a JPA-defined {@link CacheStoreMode}
*
* @see #setCacheMode(CacheMode)
*
* @since 6.2
*/
void setCacheStoreMode(CacheStoreMode cacheStoreMode);
@ -234,6 +240,8 @@ public interface Session extends SharedSessionContract, EntityManager {
* @param cacheRetrieveMode a JPA-defined {@link CacheRetrieveMode}
*
* @see #setCacheMode(CacheMode)
*
* @since 6.2
*/
void setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode);
@ -715,6 +723,8 @@ public interface Session extends SharedSessionContract, EntityManager {
*
* @param object a persistent or transient instance
* @param lockOptions the lock options
*
* @since 6.2
*/
void lock(Object object, LockOptions lockOptions);
@ -1024,6 +1034,8 @@ public interface Session extends SharedSessionContract, EntityManager {
* @param object a detached persistent instance
*
* @return the persistent instance or proxy
*
* @since 6.0
*/
<T> T getReference(T object);
@ -1141,6 +1153,8 @@ public interface Session extends SharedSessionContract, EntityManager {
* @param filterName the name of the filter to be enabled.
*
* @return the {@link Filter} instance representing the enabled filter.
*
* @see org.hibernate.annotations.FilterDef
*/
Filter enableFilter(String filterName);

View File

@ -277,6 +277,8 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
* A {@link SchemaManager} with the same default catalog and schema as
* pooled connections belonging to this factory. Intended mostly as a
* convenience for writing tests.
*
* @since 6.2
*/
SchemaManager getSchemaManager();
@ -356,6 +358,8 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
*
* @return The set of fetch profile names given by
* {@link org.hibernate.annotations.FetchProfile} annotations.
*
* @since 6.2
*/
Set<String> getDefinedFetchProfileNames();

View File

@ -179,6 +179,8 @@ public interface StatelessSession extends SharedSessionContract {
* @param association a lazy-loaded association
*
* @see org.hibernate.Hibernate#initialize(Object)
*
* @since 6.0
*/
void fetch(Object association);
}

View File

@ -8,7 +8,6 @@ package org.hibernate.annotations;
import java.lang.annotation.Retention;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorType;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
@ -17,12 +16,21 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Simplified form for describing the discriminator value mapping as a discrete
* set. Follows the pattern of JPA's {@link DiscriminatorColumn#discriminatorType()}.
* <p/>
* Can be used in conjunction with {@link JdbcType} or {@link JdbcTypeCode} to
* further describe the underlying mapping. {@link JdbcType} or {@link JdbcTypeCode}
* can also be used without {@code AnyDiscriminator}.
* A simplified way to specify the type of the discriminator in an {@link Any}
* mapping, using the JPA-defined {@link DiscriminatorType}. This annotation
* must be used in combination with {@link jakarta.persistence.Column} to fully
* describe the discriminator column for an {@code @Any} relationship.
* <p>
* {@code @AnyDiscriminator} is quite similar to
* {@link jakarta.persistence.DiscriminatorColumn#discriminatorType()} in
* single-table inheritance mappings, but it describes a discriminator held
* along with the foreign key in the referring side of a discriminated
* relationship.
* <p>
* This annotation may be used in conjunction with {@link JdbcType} or
* {@link JdbcTypeCode} to more precisely specify the type mapping. On the
* other hand, {@link JdbcType} or {@link JdbcTypeCode} may be used without
* {@code @AnyDiscriminator}.
*
* @see Any
*
@ -32,7 +40,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention( RUNTIME )
public @interface AnyDiscriminator {
/**
* The simplified discriminator value mapping
* The type of the discriminator, as a JPA {@link DiscriminatorType}.
* For more precise specification of the type, use {@link JdbcType}
* or {@link JdbcTypeCode}.
*/
DiscriminatorType value() default DiscriminatorType.STRING;
}

View File

@ -22,6 +22,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </ul>
*
* @author Emmanuel Bernard
*
* @see DialectOverride.Check
*/
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)

View File

@ -27,6 +27,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* @author Steve Ebersole
*
* @see GeneratedColumn
* @see DialectOverride.ColumnDefault
*/
@Target( {FIELD, METHOD} )
@Retention( RUNTIME )

View File

@ -35,6 +35,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* to all versions earlier than the given version.
* </ul>
*
* @since 6.0
* @author Gavin King
*/
@Incubating

View File

@ -20,6 +20,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* Used in place of the JPA {@link jakarta.persistence.DiscriminatorColumn}.
*
* @see Formula
* @see DialectOverride.DiscriminatorFormula
*
* @author Emmanuel Bernard
* @author Steve Ebersole

View File

@ -13,7 +13,9 @@ import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Optional annotation to express Hibernate specific discriminator properties.
* Optional annotation used in conjunction with the JPA-defined
* {@link jakarta.persistence.DiscriminatorColumn} annotation to
* express Hibernate-specific discriminator properties.
*
* @author Hardy Ferentschik
*/
@ -21,15 +23,21 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface DiscriminatorOptions {
/**
* "Forces" Hibernate to specify the allowed discriminator values, even when retrieving all instances of
* the root class. {@code true} indicates that the discriminator value should be forced; Default is
* {@code false}.
* If enabled, allowed discriminator values are always explicitly
* enumerated in {@code select} queries, even when retrieving all
* instances of a root entity and its subtypes. This is useful if
* there are discriminator column values which do <em>not</em>
* map to any subtype of the root entity type.
*
* @return {@code true} if allowd discriminator values must always
* by explicitly enumerated
*/
boolean force() default false;
/**
* Set this to {@code false} if your discriminator column is also part of a mapped composite identifier.
* It tells Hibernate not to include the column in SQL INSERTs. Default is {@code true}.
* Should be {@code false} if a discriminator column is also part
* of a mapped composite identifier, and should not be duplicated
* in SQL {@code INSERT} statements.
*/
boolean insert() default true;
}

View File

@ -16,36 +16,89 @@ import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Add filters to an entity or a target entity of a collection.
* Specifies that an entity or collection is affected by a named
* filter declared using {@link FilterDef}, and allows the
* {@linkplain FilterDef#defaultCondition default filter condition}
* to be overridden for the annotated entity or collection role.
* <p>
* For example, we might apply a filter named {@code Current} to
* an entity like this:
* <pre>
* {@code
* @Entity
* @Filter(name = "Current",
* deduceAliasInjectionPoints = false,
* condition = "{alias}.year = extract(year from current_date)")
* class Course {
* @Id @GeneratedValue Long id;
* int year;
* ...
* }
* }
* </pre>
* <p>
* If an entity or collection has no {@code @Filter} annotation
* with the name of a given filter, it is not affected by that
* filter.
*
* @author Emmanuel Bernard
* @author Matthew Inger
* @author Magnus Sandberg
* @author Rob Worsnop
*
* @see FilterJoinTable
* @see DialectOverride.Filters
*/
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
@Repeatable(Filters.class)
public @interface Filter {
/**
* The filter name.
* The name of the filter declared using {@link FilterDef}.
*/
String name();
/**
* The filter condition. If empty, the default condition from the correspondingly named {@link FilterDef} is used.
* The filter condition, a SQL expression used for filtering
* the rows returned by a query when the filter is enabled.
* If not specified, the default filter condition given by
* {@link FilterDef#defaultCondition} is used.
* <p>
* By default, aliases of filtered tables are automatically
* interpolated into the filter condition, before any token
* that looks like a column name. Occasionally, when the
* interpolation algorithm encounters ambiguity, the process
* of alias interpolation produces broken SQL. In such cases,
* alias interpolation may be controlled explicitly using
* either {@link #deduceAliasInjectionPoints} or
* {@link #aliases}.
*/
String condition() default "";
/**
* If true, automatically determine all points within the condition fragment that an alias should be injected.
* Otherwise, injection will only replace instances of explicit "{alias}" instances or
* {@link SqlFragmentAlias} descriptors.
* Determines how tables aliases are interpolated into the
* {@link #condition} SQL expression.
* <ul>
* <li>if {@code true}, and by default, an alias is added
* automatically to every column occurring in the SQL
* expression, but
* <li>if {@code false}, aliases are only interpolated where
* an explicit placeholder of form {@code {alias}} occurs
* in the SQL expression.
* <li>Finally, if {@link #aliases explicit aliases} are
* specified, then alias interpolation happens only for
* the specified aliases.
* </ul>
*/
boolean deduceAliasInjectionPoints() default true;
/**
* The alias descriptors for injection.
* Explicitly specifies how aliases are interpolated into
* the {@link #condition} SQL expression. Each {@link
* SqlFragmentAlias} specifies a placeholder name and the
* table whose alias should be interpolated. Placeholders
* are of form {@code {name}} where {@code name} matches
* a {@link SqlFragmentAlias#alias}.
*/
SqlFragmentAlias[] aliases() default {};
}

View File

@ -14,27 +14,77 @@ import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Filter definition. Defines a name, default condition and parameter types (if any).
* Declares a filter, specifying its {@linkplain #name}, optionally,
* a {@linkplain #defaultCondition() default condition}, and its
* {@linkplain #parameters parameter names and types}, if it has
* parameters.
* <p>
* Every entity or collection which is affected by a named filter
* declared using this annotation must be explicitly annotated
* {@link Filter @Filter}, and the name of this filter definition
* must be {@linkplain Filter#name given}. The {@code @Filter}
* annotation may override the default condition specified by this
* annotation using {@link Filter#condition}.
* <p>
* For example, if a filter is declared as follows:
* <pre>
* {@code
* @FilterDef(name = "Current",
* defaultCondition = "status<>'DELETED'")
* package org.hibernate.domain;
* }
* </pre>
* Then the filter may be applied to an entity type like this:
* <pre>
* {@code
* @Entity
* @Filter(name = "Current")
* class Record {
* @Id @GeneratedValue Long id;
* @Enumerated(STRING) Status status;
* ...
* }
* }
* </pre>
* <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.
* <pre>
* {@code session.enableFilter("Current");}
* </pre>
*
* @author Matthew Inger
* @author Emmanuel Bernard
*
* @see org.hibernate.Filter
* @see DialectOverride.FilterDefs
*/
@Target({TYPE, PACKAGE})
@Retention(RUNTIME)
@Repeatable(FilterDefs.class)
public @interface FilterDef {
/**
* The filter name.
* The name of the declared filter.
*/
String name();
/**
* The default filter condition.
* The default filter condition, a SQL expression used for
* filtering the rows returned by a query when the filter is
* enabled. This default condition may be overridden by any
* entity or collection to which the filter applies using
* {@link Filter#condition}.
* <p>
* If every entity and collection to which the filter applies
* explicitly specifies its own filter condition, then the
* default condition is unnecessary, and so this member is
* optional.
*/
String defaultCondition() default "";
/**
* The filter parameter definitions.
* The names and types of the parameters of the filter.
*/
ParamDef[] parameters() default {};
}

View File

@ -13,33 +13,66 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Add filters to a join table collection.
* Specifies that the join table of a collection is affected by a
* named filter declared using {@link FilterDef}, and allows the
* {@linkplain FilterDef#defaultCondition default filter condition}
* to be overridden for the annotated entity or collection role.
*
* @author Emmanuel Bernard
* @author Rob Worsnop
*
* @see Filter
*/
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(FilterJoinTables.class)
public @interface FilterJoinTable {
/**
* The filter name.
* The name of the filter declared using {@link FilterDef}.
*/
String name();
/**
* The filter condition. If empty, the default condition from the correspondingly named {@link FilterDef} is used.
* The filter condition, a SQL expression used for filtering
* the rows returned by a query when the filter is enabled.
* If not specified, the default filter condition given by
* {@link FilterDef#defaultCondition} is used.
* <p>
* By default, aliases of filtered tables are automatically
* interpolated into the filter condition, before any token
* that looks like a column name. Occasionally, when the
* interpolation algorithm encounters ambiguity, the process
* of alias interpolation produces broken SQL. In such cases,
* alias interpolation may be controlled explicitly using
* either {@link #deduceAliasInjectionPoints} or
* {@link #aliases}.
*/
String condition() default "";
/**
* Do we need to determine all points within the condition fragment that are alias injection points? Or
* are injection points already marked?
* Determines how tables aliases are interpolated into the
* {@link #condition} SQL expression.
* <ul>
* <li>if {@code true}, and by default, an alias is added
* automatically to every column occurring in the SQL
* expression, but
* <li>if {@code false}, aliases are only interpolated where
* an explicit placeholder of form {@code {alias}} occurs
* in the SQL expression.
* <li>Finally, if {@link #aliases explicit aliases} are
* specified, then alias interpolation happens only for
* the specified aliases.
* </ul>
*/
boolean deduceAliasInjectionPoints() default true;
/**
* The alias descriptors for injection.
* Explicitly specifies how aliases are interpolated into
* the {@link #condition} SQL expression. Each {@link
* SqlFragmentAlias} specifies a placeholder name and the
* table whose alias should be interpolated. Placeholders
* are of form {@code {name}} where {@code name} matches
* a {@link SqlFragmentAlias#alias}.
*/
SqlFragmentAlias[] aliases() default {};
}

View File

@ -46,6 +46,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
*
* @author Emmanuel Bernard
* @author Steve Ebersole
*
* @see DialectOverride.Formula
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)

View File

@ -16,13 +16,16 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Specifies that a column is defined using a DDL {@code generated always as} clause
* or equivalent, and that Hibernate should fetch the generated value from the
* database after each SQL {@code INSERT} or {@code UPDATE}.
*
* @author Gavin King
* Specifies that a column is defined using a DDL {@code generated always as}
* clause or equivalent, and that Hibernate should fetch the generated value
* from the database after each SQL {@code INSERT} or {@code UPDATE}.
*
* @see ColumnDefault
*
* @since 6.0
* @author Gavin King
*
* @see DialectOverride.GeneratedColumn
*/
@Target( {FIELD, METHOD} )
@Retention( RUNTIME )

View File

@ -27,6 +27,8 @@ public enum GenerationTime {
INSERT( GenerationTiming.INSERT ),
/**
* Indicates the value is generated on update.
*
* @since 6.2
*/
UPDATE( GenerationTiming.UPDATE ),
/**

View File

@ -16,6 +16,8 @@ import org.hibernate.id.IdentifierGenerator;
/**
* Meta-annotation used to mark another annotation as providing configuration
* for a custom {@link IdentifierGenerator}.
*
* @since 6.0
*/
@Target( value = ElementType.ANNOTATION_TYPE )
@Retention( RetentionPolicy.RUNTIME )

View File

@ -18,6 +18,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* instead of a {@linkplain jakarta.persistence.JoinColumn column name}.
*
* @author Sharath Reddy
*
* @see DialectOverride.JoinFormula
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)

View File

@ -36,6 +36,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
*
* @author Emmanuel Bernard
* @author Steve Ebersole
*
* @see DialectOverride.OrderBy
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)

View File

@ -12,7 +12,7 @@ import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Details about a parameter defined in a FilterDef.
* Details about a parameter declared in a {@link FilterDef}.
* <p/>
* Mainly used to support cases where the proper {@link #type type}
* cannot be deduced by Hibernate.

View File

@ -9,16 +9,22 @@ package org.hibernate.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Describe aliases for filters.
* Defines an interpolated alias occurring in a SQL
* {@linkplain Filter#condition() filter condition}.
* Aliases are interpolated where placeholders of the
* form {@code {name}} occur, where {@code name} is
* the value specified by {@link #alias}.
* <p>
* It's usually necessary to specify only one of
* {@link #entity} and {@link #table} to uniquely
* identify the alias that should be interpolated.
*
* @author Rob Worsnop
*/
@Target({METHOD, FIELD})
@Target({})
@Retention(RUNTIME)
public @interface SqlFragmentAlias {
/**

View File

@ -22,6 +22,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
*
* @see org.hibernate.context.spi.CurrentTenantIdentifierResolver
*
* @since 6.0
* @author Gavin King
*/
@ValueGenerationType(generatedBy = TenantIdGeneration.class)

View File

@ -27,6 +27,8 @@ import static java.lang.annotation.ElementType.METHOD;
* @see TimeZoneStorage
* @see TimeZoneStorageType#COLUMN
* @see TimeZoneStorageType#AUTO
*
* @since 6.0
*/
@Incubating
@Retention(RetentionPolicy.RUNTIME)

View File

@ -39,6 +39,8 @@ import static java.lang.annotation.ElementType.METHOD;
* @author Steve Ebersole
* @author Andrea Boriero
* @see TimeZoneColumn
*
* @since 6.0
*/
@Incubating
@Retention(RetentionPolicy.RUNTIME)

View File

@ -15,6 +15,8 @@ import org.hibernate.dialect.Dialect;
* @author Christian Beikov
* @author Steve Ebersole
* @author Andrea Boriero
*
* @since 6.0
*/
@Incubating
public enum TimeZoneStorageType {

View File

@ -20,6 +20,8 @@ import static java.lang.annotation.ElementType.METHOD;
* The type of the identifier attribute may be {@link UUID} or {@link String}.
*
* @author Steve Ebersole
*
* @since 6.0
*/
@IdGeneratorType( org.hibernate.id.uuid.UuidGenerator.class )
@Retention(RetentionPolicy.RUNTIME)

View File

@ -25,6 +25,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* disabled. They're therefore much less flexible than {@link Filter filters}.
*
* @see Filter
* @see DialectOverride.Where
*
* @author Emmanuel Bernard
*/

View File

@ -17,6 +17,7 @@ import org.hibernate.Incubating;
*
* @see org.hibernate.SessionFactory#getSchemaManager()
*
* @since 6.2
* @author Gavin King
*/
@Incubating