Package org.hibernate.annotations
The JPA specification perfectly nails many aspects of the O/R persistence problem, but here we address some areas where it falls short.
Basic types in JPA
A basic type handles the persistence of an attribute of an entity or embeddable object that is stored in exactly one database column.
JPA supports a very limited set of built-in basic types.
Category | Package | Types |
Primitive types | boolean , int , double , etc. |
|
Primitive wrappers | java.lang |
Boolean , Integer , Double , etc. |
Strings | java.lang |
String |
Arbitrary-precision numeric types | java.math | BigInteger , BigDecimal |
Date/time types | java.time |
LocalDate , LocalTime , LocalDateTime , OffsetDateTime , Instant |
Deprecated date/time types | java.util |
Date , Calendar |
Deprecated JDBC date/time types | java.sql |
Date , Time , Timestamp |
Binary and character arrays | byte[] , char[] |
|
UUIDs | java.util |
UUID |
Enumerated types | Any enum |
|
Serializable types | Any java.io.Serializable |
JPA does provide converters as an extensibility mechanism, but its converters are only useful for classes which have an equivalent representation as one of the types listed above.
Basic value type mappings
By contrast, Hibernate has an embarrassingly rich set of abstractions for modelling basic types, which can be initially confusing.
Note that the venerable interface Type
abstracts over all
sorts of field and property types, not only basic types. In modern Hibernate, programs
should avoid direct use of this interface.
Instead, a program should use either a "compositional" basic type, or in more extreme
cases, a UserType
.
A basic type is a composition of a
JavaType
with aJdbcType
, and possibly a JPAAttributeConverter
, and the process of composition is usually somewhat implicit.A converter may be selected using the JPA
Convert
annotation, or it may be applied implicitly.A
JavaType
orJdbcType
may be indicated explicitly using the following annotations:But these annotation also influence the choice:
Furthermore, a
JavaTypeRegistration
orJdbcTypeRegistration
allows the choice ofJavaType
orJdbcType
to be made implicitly.A compositional type mapping also comes with a
MutabilityPlan
, which is usually chosen by theJavaType
, but which may be overridden using theMutability
annotation.
Note that
JavaType
,JdbcType
,JdbcTypeCode
andMutability
all come in specialized flavors for handling map keys, list indexes, and so on.Alternatively, a program may implement the
UserType
interface and associate it with a field or property- explicitly, using the
@Type
annotation, or - implicitly, using the
@TypeRegistration
annotation.
There are some specialized flavors of the
@Type
annotation too.- explicitly, using the
These two approaches cannot be used together. A UserType
always takes precedence
over the compositional approach.
All the typing annotations just mentioned may be used as meta-annotations. That is, it's possible to define a new typing annotation like this:
@JavaType(ThingJavaType.class) @JdbcTypeCode(JSON) @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JsonThing {}The annotation may then be applied to fields and properties of entities and embeddable objects:
@JsonThing Thing myThing;The packages
org.hibernate.type.descriptor.java
and
org.hibernate.type.descriptor.jdbc
contain the built-in implementations of
JavaType
and JdbcType
, respectively.
See the User Guide or the package org.hibernate.type
for further
discussion.
Composite types
A composite type is a type which maps to multiple columns. An example of a composite type is an embeddable object, but this is not the only sort of composite type in Hibernate.
A program may implement the CompositeUserType
interface and associate it with a field or property:
- explicitly, using the
@CompositeType
annotation, or - implicitly, using the
@CompositeTypeRegistration
annotation.
Second level cache
When we make a decision to store an entity in the second-level cache, we must decide much more than just whether "to cache or not to cache". Among other considerations:
- we must assign cache management policies like an expiry timeout, whether to use FIFO-based eviction, whether cached items may be serialized to disk, and
- we must also take great care in specifying how concurrent access to cached items is managed.
In a multi-user system, these policies always depend quite sensitively on the nature of the given entity type, and cannot reasonably be fixed at a more global level.
With all the above considerations in mind, we strongly recommend the use of the
Hibernate-defined annotation Cache
to assign
entities to the second-level cache.
The JPA-defined Cacheable
annotation is almost useless
to us, since:
- it provides no way to specify any information about the nature of the cached entity and how its cache should be managed, and
- it may not be used to annotate associations.
As an aside, the SharedCacheMode
enumeration is even worse:
its only sensible values are NONE
and ENABLE_SELECTIVE
. The options
ALL
and DISABLE_SELECTIVE
fit extremely poorly with the practices
advocated above.
Generated values
JPA supports generated identifiers, that is, surrogate primary keys, with four useful built-in types of id generation.
In JPA, an id generator is identified on the basis of a stringly-typed name, and this provides a reasonably natural way to integrate custom generators.
JPA does not define any way to generate the values of other fields or properties of the entity.
Hibernate 6 takes a different route, which is both more typesafe, and much more extensible.
- The interfaces
BeforeExecutionGenerator
andOnExecutionGenerator
provide an extremely open-ended way to incorporate custom generators. - The meta-annotations
IdGeneratorType
andValueGenerationType
may be used to associate a generator with a user-defined annotation. This annotation is an indirection between the generator itself, and the persistent attributes it generates. - This generator annotation may then by used to annotate
@Id
attributes,@Version
attributes, and other@Basic
attributes to specify how their values are generated.
This package includes a number built-in generator annotations, including
UuidGenerator
,
CurrentTimestamp
,
TenantId
,
Generated
, and
GeneratedColumn
.
Natural ids
The use of surrogate keys is highly recommended, making it much easier to evolve a database schema over time. But every entity should also have a "natural" unique key: a subset of fields which, taken together, uniquely identify an instance of the entity in the business or scientific domain.
The NaturalId
annotation is used to identify
the natural key of an entity, and urge its use.
The NaturalIdCache
annotation enables the use
of the second-level cache for when an entity is loaded by natural id. Retrieval
by natural id is a very common thing to do, and so the cache can often be helpful.
Filters
Filters are an extremely powerful feature of Hibernate, allowing the definition of parameterized families of filtered "views" of the domain data. They're also easy to use, with the minor caveat that they require the developer to express filtering expressions in native SQL.
- The
FilterDef
annotation defines a named filter, declares its parameters, and might specify a filtering expression used by default. There should be exactly one of these annotations per filter name. - The
Filter
annotation is used to identify which entities and associations are affected by the filter, and provide a more specific filtering condition.
Note that a filter has no affect unless it is enabled in a particular session.
Optimistic locking
JPA defines theVersion
annotation for optimistic
locking based on an integral version number or Timestamp
.
Hibernate allows this annotation to be used with other datetime types including
Instant
.
A field may be explicitly excluded from optimistic lock checking using
@OptimisticLock(excluded=true)
.
This standard JPA approach is the recommended approach when working with a newly-designed database schema. But when working with a legacy database with tables having no version or update timestamp column, an alternative approach is supported:
@OptimisticLocking(ALL)
specifies that optimistic lock checking should be done by comparing the values of all columns, and@OptimisticLocking(DIRTY)
specifies that optimistic lock checking should be done by checking the values of only the columns which are being set to new values.
For more detail, see OptimisticLocking
.
Dialect-specific native SQL
Many annotations in this package allow the specification of native SQL expressions or even complete statements. For example:
Formula
allows a field or property to map to an arbitrary SQL expression instead of a column,Check
specifies a check constraint condition,ColumnDefault
specifies a default value, andGeneratedColumn
specifies a generated value,Filter
andSQLRestriction
each specify a restriction written in SQL,SQLOrder
specifies an ordering written in SQL, andSQLSelect
,SQLUpdate
,SQLInsert
, andSQLDelete
allow a whole handwritten SQL statement to be given in place of the SQL generated by Hibernate.
A major disadvantage to annotation-based mappings for programs which target multiple databases is that there can be only one source of metadata which must work on every supported database. Fortunately, there's a—slightly inelegant—solution.
The annotations belonging to DialectOverride
allow native
SQL to be overridden for a particular SQL dialect.
For example @DialectOverride.Formula
may be used to customize a @Formula
for a given version
of a given database.
-
ClassDescriptionMaps a to-one cardinality association taking values over several entity types which are not related by the usual entity inheritance, using a discriminator value stored on the referring side of the relationship.A simplified way to specify the type of the discriminator in an
Any
mapping, using the JPA-definedDiscriminatorType
.Defines how to handle discriminator values which are not explicitly mapped with AnyDiscriminatorValue.Specifies the mapping of a single any-valued discriminator value to its corresponding entity type.List ofAnyDiscriminatorValue
s.Specifies the Java class to use for the foreign key handling related to anAny
mapping.Form ofJavaType
used to describe the foreign-key part of an ANY mapping.Form ofJdbcTypeCode
used to describe the foreign key part of anAny
mapping.Specifies the maximum length of a SQL array type mapped by the annotated attribute.Specifies an attribute access strategy to use.Associates a user-defined annotation with anAttributeBinder
, allowing the annotation to drive some custom model binding.Specifies a maximum batch size for batch fetching of the annotated entity or collection.Marks a root entity or collection for second-level caching, and specifies: a named cache region in which to store the state of instances of the entity or collection, and an appropriate cache concurrency policy, given the expected data access patterns affecting the entity or collection.Identifies policies for managing concurrent access to the shared second-level cache.Describes the data layout used for storing an object into the query cache.Deprecated.Deprecated.Use the JPA-definedCascadeType
Specifies acheck
constraint to be included in the generated DDL.A list ofCheck
s.Specifies a collation to use when generating DDL for the column mapped by the annotated field or property.Describe an identifier column for a bag.Form ofJavaType
for describing the id of an id-bag mapping.Form ofJdbcType
for describing the id of an id-bag mapping.Form ofJdbcTypeCode
for describing the id of an id-bag mapping.Form ofMutability
for describing the id of an id-bag mappingForm ofType
for describing the id of an id-bag mapping.Names a custom collection type for a persistent collection.Allows to register aUserCollectionType
to use as the default for the specified classification of collection.Repeatable container forCollectionTypeRegistration
Specifies that a column has adefault
value specified in DDL.Support an array of columns.Specifies custom SQL expressions used to read and write to the column mapped by the annotated persistent attribute in all generated SQL involving the annotated persistent attribute.Plural annotation for @ColumnTransformer.Deprecated.Prefer Table.comment()Deprecated.Per Comment, prefer Table.comment()Specifies a customCompositeUserType
for the annotated attribute mapping.Registers a custom composite user type implementation to be used by default for all references to a particular embeddable class.Grouping ofCompositeTypeRegistration
AnnotatingConcreteProxy
on the root entity class of an inheritance hierarchy will allow types of that hierarchy to always produce proxies that resolve to the concrete subtype class.Registers anAttributeConverter
.Specifies that the annotated field of property is a generated creation timestamp.Specifies that the annotated field of property is a generated timestamp, and also specifies the timing of the timestamp generation, and whether it is generated in Java or by the database:source = VM
indicates that the virtual machine current instant is used, andsource = DB
indicates that the databasecurrent_timestamp
function should be used.Allows certain annotations to be overridden in a given SQLDialect
.Specializes aCheck
in a certain dialect.Specializes aColumnDefault
in a certain dialect.Specializes aDiscriminatorFormula
in a certain dialect.SpecializesFilterDefs
in a certain dialect.SpecializesFilters
in a certain dialect.Specializes aFormula
in a certain dialect.Specializes aGeneratedColumn
in a certain dialect.Specializes aJoinFormula
in a certain dialect.Marks an annotation type as a dialect-specific override for some other annotation type.Specializes aSQLDelete
in a certain dialect.Specializes aSQLDeleteAll
in a certain dialect.Specializes aSQLInsert
in a certain dialect.Specializes anSQLOrder
in a certain dialect.Specializes aSQLRestriction
in a certain dialect.Specializes aSQLSelect
in a certain dialect.Specializes aSQLUpdate
in a certain dialect.Identifies a database version.Specifies an expression written in native SQL as the discriminator for an entity inheritance hierarchy.Optional annotation used in conjunction with the JPA-definedDiscriminatorColumn
annotation to express Hibernate-specific discriminator properties.Specifies that SQLinsert
statements for the annotated entity are generated dynamically, and only include the columns to which a non-null value must be assigned.Specifies that SQLupdate
statements for the annotated entity are generated dynamically, and only include columns which are actually being updated.Specifies a custom instantiator for a specific embeddedRegisters a custom instantiator implementation to be used for all references to a particularEmbeddable
.Grouping ofEmbeddableInstantiatorRegistration
Specifies the default fetching method for the annotated association.Enumerates methods for fetching an association from the database.Defines a fetch profile, by specifying itsFetchProfile.name()
, together with a list of fetch strategy overrides.Overrides the fetching strategy for a particular association in the named fetch profile being defined.Overrides the fetching strategy for the annotated association in a certain named fetch profile.A group ofFetchProfileOverride
s.Collects together multiple fetch profiles.Specifies that an entity or collection is affected by a named filter declared using@FilterDef
, and allows the default filter condition to be overridden for the annotated entity or collection role.Declares a filter, specifying its FilterDef.name(), optionally, a default condition, and its parameter names and types, if it has parameters.Array of filter definitions.Specifies that the join table of a collection is affected by a named filter declared usingFilterDef
, and allows the default filter condition to be overridden for the annotated entity or collection role.Add multiple@FilterJoinTable
to a collection.Add multiple@Filters
.Deprecated.useQueryFlushMode
Specifies an expression written in native SQL that is used to read the value of an attribute instead of storing the value in aColumn
.Deprecated, for removal: This API element is subject to removal in a future version.UseColumn.secondPrecision()
which was introduced in JPA 3.2Specifies that the value of the annotated property is generated by the database.Specifies that a column is defined using a DDLgenerated always as
clause or equivalent, and that Hibernate should fetch the generated value from the database after each SQLINSERT
orUPDATE
.Deprecated.Use the new approach based onIdGeneratorType
.Deprecated.sinceGenericGenerator
is deprecated.Specifies a custom HQL/JPQL query to be used in place of the default SQL generated by Hibernate when an entity or collection is fetched from the database by id.Meta-annotation used to mark another annotation as providing configuration for a custom identifier generator.Marks an entity, collection, or attribute of an entity as immutable.Marks an arbitrary class as available for use in HQL queries by its unqualified name.Marks the canonical constructor to be used for instantiation of an embeddable.Specify an explicitBasicJavaType
to use for a particular column mapping.Registers aBasicJavaType
as the default Java type descriptor for the givenJavaTypeRegistration.javaType()
.Grouping ofJavaTypeRegistration
See notes onJavaTypeRegistration
about using on packages versus use on classesSpecifies an explicitJdbcType
to use for a particular column mapping. When applied to a Map-valued attribute, describes the Map value.Specifies the JDBC type-code to use for the column mapping. When applied to a Map-valued attribute, describes the Map value.Grouping ofJdbcTypeRegistration
See notes onJdbcTypeRegistration
about using on packages versus use on classesSpecifies a join condition based on an arbitrary native SQL formula instead of a column name.Specifies the fetch group for a persistent attribute of an entity class.Specifies the base value for the order column of a persistent list or array, that is, the order column value of the first element of the list or array.Form ofJavaType
for describing the column mapping for the index of aList
or array.Form ofJdbcType
for describing the column mapping for the index of aList
or array.Form ofJdbcTypeCode
for describing the column mapping for the index of aList
or array.Maps a to-many cardinality association taking values over several entity types which are not related by the usual entity inheritance, using a discriminator value stored in an association table.Form ofCompositeType
for use with map-keysForm ofJavaType
for describing the key of a MapForm ofJdbcType
for describing the key of a MapForm ofJdbcTypeCode
for describing the key of a MapForm ofMutability
for describing the key of a MapForm ofType
for use with map keys.Specifies aMutabilityPlan
for a basic value mapping.A grouping ofNamedNativeQuery
definitions.Declares a named query written in native SQL.A grouping ofNamedQuery
definitions.Declares a named query written in HQL or JPQL.Specifies that the annotated character data should be stored with nationalization support.Generator that picks a strategy based on the dialect.Specifies that a field or property of an entity class is part of the natural id of the entity.Specifies that mappings from the natural id values of the annotated entity to the corresponding entity id values should be cached in the shared second-level cache.Indicates that a many to one, one to one, or many to many association maps to a column holding foreign keys, but without a foreign key constraint, and which may therefore violate referential integrity.Specifies how Hibernate should handle the case of an orphaned foreign key with no associated row in the referenced table.Specifies anon delete
action for a foreign key constraint.Enumerates the possible actions for theon delete
clause of a foreign key constraint.Specifies whether mutating the annotated attribute should trigger an increment to theversion
of the entity instance.Specifies how optimistic lock checking works for the annotated entity.Enumerates the possible optimistic lock checking strategies.Details about a parameter declared in aFilterDef
.Generic parameter (basically a key/value combination) used to parametrize other annotations.Reference the property as a pointer back to the owner (generally the owning entity).Identifies a field of an entity that holds the partition key of a table.Allows to specify the target of a foreign-key using a "target attribute" as opposed to join column(s).Configures the layout for the entity or collection data in a query cache.Deprecated.Use anExpectation
class instead.Specifies that arowid
-like column or pseudo-column should be used as the row locator in CRUD operations for an entity, instead of the primary key of the table.Specifies how the row of aSecondaryTable
should be managed.A grouping ofSecondaryRow
s.Describes a soft-delete indicator mapping.Used as the default for SoftDelete.converter(), indicating that dialect and settings resolution should be used.Enumeration of defines styles of soft-deleteDeprecated.useCurrentTimestamp
insteadSpecifies the source of a generated value, either the virtual machine, or the database.Specifies a custom SQL DML statement to be used in place of the default SQL generated by Hibernate when an entity or collection row is deleted from the database.Specifies a custom SQL DML statement to be used in place of the default SQL generated by Hibernate when an entire collection is deleted from the database.A grouping ofSQLDelete
s.Defines an interpolated alias occurring in a SQL filter condition.Specifies a custom SQL DML statement to be used in place of the default SQL generated by Hibernate when an entity or collection row is inserted in the database.A grouping ofSQLInsert
s.Specifies a restriction written in native SQL to add to the generated SQL when querying the join table of a collection.Order a collection using an expression or list of expression written in native SQL.Specifies a restriction written in native SQL to add to the generated SQL for entities or collections.Specifies a custom SQL query to be used in place of the default SQL generated by Hibernate when an entity or collection is loaded from the database by id.Specifies a custom SQL DML statement to be used in place of the default SQL generated by Hibernate when an entity or collection row is updated in the database.A grouping ofSQLUpdate
s.Specifies the UDT (user defined type) name for the annotated embeddable type or embedded attribute.Maps an immutable and read-only entity to a given SQLselect
expression.Specifies a table or tables that hold state mapped by the annotated entity or collection.Deprecated.use annotation members of JPA association mapping annotations, for example,OneToMany.targetEntity()
Identifies a field of an entity that holds a tenant id in discriminator-based multitenancy.Specifies the mapped column for storing the time zone information, for use in conjunction withTimeZoneStorageType.COLUMN
orTimeZoneStorageType.AUTO
.Specifies how the time zone information of a persistent property or field should be persisted.Describes the storage of timezone information for zoned datetime types, in particular, for the typesOffsetDateTime
andZonedDateTime
.Specifies a customUserType
for the annotated attribute mapping.Associates a user-defined annotation with aTypeBinder
, allowing the annotation to drive some custom model binding.Registers a custom user type implementation to be used by default for all references to a particular class of basic type.Grouping ofTypeRegistration
Specifies that the annotated field of property is a generated update timestamp. The timestamp is regenerated every time an entity instance is updated in the database.Specifies that an entity identifier is generated as an IETF RFC 4122 UUID.Represents a kind of UUID, that is, what RFC 4122 calls a "version".Meta-annotation used to mark another annotation as providing configuration for a custom value generation strategy.Maps an entity to a database view.
CascadeType