The JPA specification perfectly nails many aspects of the O/R persistence problem, but here we address some areas where it falls short.
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.
By contrast, Hibernate has an embarrassingly rich set of abstractions for modelling basic types, which can be initially confusing.
Note that the venerable interface org. 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 org.
with a org., and possibly a JPA
jakarta., and the process of composition is
usually somewhat implicit.
A converter may be selected using the JPA jakarta.
annotation, or it may be applied implicitly.
A JavaType or JdbcType may be indicated explicitly
using the following annotations:
But these annotation also influence the choice:
Furthermore, a org. or
org. allows the choice
of JavaType or JdbcType to be made implicitly.
A compositional type mapping also comes with a
org., which is usually
chosen by the JavaType, but which may be overridden using the
org. annotation.
Note that org., org.,
org. and org.
all come in specialized flavors for handling map keys, list indexes, and so on.
Alternatively, a program may implement the org.
interface and associate it with a field or property
@Type annotation,
or
@TypeRegistration
annotation.
There are some specialized flavors of the @Type annotation too.
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. for further
discussion.
A program may implement the org.
interface and associate it with a field or property:
@CompositeType
annotation, or
@CompositeTypeRegistration
annotation.
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:
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 org. to assign
entities to the second-level cache.
The JPA-defined jakarta. annotation is almost useless
to us, since:
As an aside, the jakarta. 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.
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.
org.hibernate.generator.BeforeExecutionGenerator
and org.hibernate.generator.OnExecutionGenerator provide an extremely
open-ended way to incorporate custom generators.
org.hibernate.annotations.IdGeneratorType and
org.hibernate.annotations.ValueGenerationType 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.
@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
org.,
org.,
org.,
org., and
org..
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 org. annotation is used to identify
the natural key of an entity, and urge its use.
The org. 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 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.
org.hibernate.annotations.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.
org.hibernate.annotations.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.
jakarta.persistence.Version annotation for optimistic
locking based on an integral version number or java.sql.Timestamp .
Hibernate allows this annotation to be used with other datetime types including
java.time.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 org..
Many annotations in this package allow the specification of native SQL expressions or even complete statements. For example:
org.hibernate.annotations.Formula allows a field or property to map to an
arbitrary SQL expression instead of a column,
org.hibernate.annotations.Check specifies a check constraint condition,
org.hibernate.annotations.ColumnDefault specifies a default value, and
org.hibernate.annotations.GeneratedColumn specifies a generated value,
org.hibernate.annotations.Filter and org.hibernate.annotations.SQLRestriction
each specify a restriction written in SQL,
org.hibernate.annotations.SQLOrder specifies an ordering written in SQL, and
org.hibernate.annotations.SQLSelect , org.hibernate.annotations.SQLUpdate ,
org.hibernate.annotations.SQLInsert , and org.hibernate.annotations.SQLDelete
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 org. allow native
SQL to be overridden for a particular SQL dialect.
For example @DialectOverride.
may be used to customize a @Formula for a given version
of a given database.
| Modifier and Type | Interface and Description |
|---|---|
| public interface | DialectOverride
Allows certain annotations to be overridden in a given SQL |
| Modifier and Type | Annotation and Description |
|---|---|
| public @interface | Any
Maps 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. |
| public @interface | AnyDiscriminator
A simplified way to specify the type of the discriminator in an |
| public @interface | AnyDiscriminatorValue
Specifies the mapping of a single any-valued discriminator value to its corresponding entity type. |
| public @interface | |
| public @interface | AnyKeyJavaClass
Specifies the Java class to use for the foreign key handling
related to an |
| public @interface | AnyKeyJavaType
Form of |
| public @interface | AnyKeyJdbcType
Form of |
| public @interface | AnyKeyJdbcTypeCode
Form of |
| public @interface | Array
Specifies the maximum length of a SQL array type mapped by the annotated attribute. |
| public @interface | AttributeAccessor
Specifies an attribute access strategy to use. |
| public @interface | AttributeBinderType
Associates a user-defined annotation with an |
| public @interface | Bag
Specifies that an attribute of type |
| public @interface | BatchSize
Specifies a maximum batch size for batch fetching of the annotated entity or collection. |
| public @interface | Cache
Marks a root entity or collection for second-level caching, and specifies:
|
| public @interface | Cascade
Specifies the persistence operations that should cascade to associated entity instances. |
| public @interface | Check
Specifies a |
| public @interface | |
| public @interface | Collate
Specifies a collation to use when generating DDL for the column mapped by the annotated field or property. |
| public @interface | CollectionId
Describe an identifier column for a bag. |
| public @interface | CollectionIdJavaType
Form of |
| public @interface | CollectionIdJdbcType
Form of |
| public @interface | CollectionIdJdbcTypeCode
Form of |
| public @interface | CollectionIdMutability
Form of |
| public @interface | CollectionIdType
Form of |
| public @interface | CollectionType
Names a custom collection type for a persistent collection. |
| public @interface | CollectionTypeRegistration
Allows to register a |
| public @interface | CollectionTypeRegistrations
Repeatable container for |
| public @interface | ColumnDefault
Specifies that a column has a |
| public @interface | Columns
Support an array of columns. |
| public @interface | ColumnTransformer
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. |
| public @interface | ColumnTransformers
Plural annotation for @ColumnTransformer. |
| public @interface | Comment
Specifies a comment that will be included in generated DDL. |
| public @interface | |
| public @interface | CompositeType
Specifies a custom |
| public @interface | CompositeTypeRegistration
Registers a custom composite user type implementation to be used by default for all references to a particular embeddable class. |
| public @interface | |
| public @interface | |
| public @interface | |
| public @interface | CreationTimestamp
Specifies that the annotated field of property is a generated creation timestamp. |
| public @interface | CurrentTimestamp
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:
|
| public @interface | DiscriminatorFormula
Specifies an expression written in native SQL as the discriminator for an entity inheritance hierarchy. |
| public @interface | DiscriminatorOptions
Optional annotation used in conjunction with the JPA-defined
|
| public @interface | DynamicInsert
Specifies that SQL |
| public @interface | DynamicUpdate
Specifies that SQL |
| public @interface | EmbeddableInstantiator
Specifies a custom instantiator for a specific embedded |
| public @interface | EmbeddableInstantiatorRegistration
Registers a custom instantiator implementation to be used
for all references to a particular |
| public @interface | |
| public @interface | Fetch
Specifies the default fetching method for the annotated association. |
| public @interface | FetchProfile
Defines a fetch profile, by specifying its |
| public @interface | FetchProfileOverride
Overrides the fetching strategy for the annotated association in a certain named fetch profile. |
| public @interface | FetchProfileOverrides
A group of |
| public @interface | FetchProfiles
Collects together multiple fetch profiles. |
| public @interface | Filter
Specifies that an entity or collection is affected by a named
filter declared using |
| public @interface | FilterDef
Declares a filter, specifying its name, optionally, a default condition, and its parameter names and types, if it has parameters. |
| public @interface | FilterDefs
Array of filter definitions. |
| public @interface | FilterJoinTable
Specifies that the join table of a collection is affected by a
named filter declared using |
| public @interface | FilterJoinTables
Add multiple |
| public @interface | Filters
Add multiple |
| public @interface | ForeignKey
Deprecated
for removal. use the JPA 2.1 Specifies a foreign key name.
jakarta. annotation
|
| public @interface | Formula
Specifies an expression written in native SQL that is used to read the value of
an attribute instead of storing the value in a |
| public @interface | Generated
Specifies that the value of the annotated property is generated by the database. |
| public @interface | GeneratedColumn
Specifies that a column is defined using a DDL |
| public @interface | GeneratorType
Deprecated
since 6.0. Marks a field or property of an entity as automatically generated by
code written in Java, before any SQL statement to ValueGenerationType and AnnotationValueGeneration
now provide a much more powerful and typesafe alternative
insert or
update the entity is executed, specifying an implementation
of ValueGenerator used for generating its values.
|
| public @interface | GenericGenerator
Defines a named identifier generator, usually an instance of the interface
|
| public @interface | GenericGenerators
Array of generic generator definitions. |
| public @interface | HQLSelect
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. This occurs when:
|
| public @interface | IdGeneratorType
Meta-annotation used to mark another annotation as providing configuration for a custom identifier generator. |
| public @interface | Immutable
Marks an entity, collection, or attribute of an entity as immutable. |
| public @interface | Imported
Marks an arbitrary class as available for use in HQL queries by its unqualified name. |
| public @interface | Index
Deprecated
Use Defines an index of a database table.
jakarta. instead.
|
| public @interface | IndexColumn
Deprecated
Prefer the standard JPA Describe an index column of a List.
jakarta. annotation,
using ListIndexBase instead of base().
|
| public @interface | Instantiator
Marks the canonical constructor to be used for instantiation of an embeddable. |
| public @interface | JavaType
Specify an explicit |
| public @interface | JavaTypeRegistration
Registers a |
| public @interface | JavaTypeRegistrations
Grouping of |
| public @interface | JdbcType
Specifies an explicit |
| public @interface | JdbcTypeCode
Specifies the JDBC type-code to use for the column mapping. |
| public @interface | JdbcTypeRegistration
Registers a |
| public @interface | JdbcTypeRegistrations
Grouping of |
| public @interface | JoinColumnOrFormula
Specifies one element of a composite join condition involving both formulas and columns. |
| public @interface | JoinColumnsOrFormulas
Specifies a composite join condition involving one or more formulas and, optionally, one or more columns. |
| public @interface | JoinFormula
Specifies a join condition based on an arbitrary native SQL formula instead of a column name. |
| public @interface | LazyCollection
Deprecated
since 6.2. Specify the laziness of a collection, either a
jakarta. or
jakarta. association,
or an jakarta..
|
| public @interface | LazyGroup
Specifies the fetch group for a persistent attribute of an entity class. |
| public @interface | LazyToOne
Deprecated
since 6.2. use JPA annotations to specify the
Specifies the machinery used to handle lazy fetching of
the annotated jakarta.
jakarta. or
jakarta. association.
|
| public @interface | ListIndexBase
Specifies the base value for the |
| public @interface | ListIndexJavaType
Form of |
| public @interface | ListIndexJdbcType
Form of |
| public @interface | ListIndexJdbcTypeCode
Form of |
| public @interface | |
| public @interface | ManyToAny
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. |
| public @interface | MapKeyCompositeType
Form of |
| public @interface | MapKeyJavaType
Form of |
| public @interface | MapKeyJdbcType
Form of |
| public @interface | MapKeyJdbcTypeCode
Form of |
| public @interface | MapKeyMutability
Form of |
| public @interface | MapKeyType
Form of |
| public @interface | Mutability
Specifies a |
| public @interface | NamedNativeQueries
A grouping of |
| public @interface | NamedNativeQuery
Declares a named query written in native SQL. |
| public @interface | NamedQueries
A grouping of |
| public @interface | NamedQuery
Declares a named query written in HQL or JPQL. |
| public @interface | Nationalized
Specifies that the annotated character data should be stored with nationalization support. |
| public @interface | NaturalId
Specifies that a field or property of an entity class is part of the natural id of the entity. |
| public @interface | NaturalIdCache
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. |
| public @interface | NotFound
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. |
| public @interface | OnDelete
Specifies an |
| public @interface | OptimisticLock
Specifies whether mutating the annotated attribute should trigger an increment
to the |
| public @interface | OptimisticLocking
Specifies how optimistic lock checking works for the annotated entity. |
| public @interface | |
| public @interface | |
| public @interface | Parameter
Generic parameter (basically a key/value combination) used to parametrize other annotations. |
| public @interface | Parent
Reference the property as a pointer back to the owner (generally the owning entity). |
| public @interface | PartitionKey
Identifies a field of an entity that holds the partition key of a table. |
| public @interface | Persister
Deprecated
since 6. Alternative depends on reason for custom persister
Specify a custom persister.
|
| public @interface | Polymorphism
Deprecated
since 6.2. This annotation is hardly ever useful.
Allows implicit polymorphism to be disabled for
an entity class hierarchy, by annotating the root entity
@Polymorphism(type=EXPLICIT).
|
| public @interface | Proxy
Deprecated
since 6.2. This annotation is almost never useful.
Allows the proxy class of an entity class to be explicitly specified.
|
| public @interface | RowId
Specifies that a |
| public @interface | SecondaryRow
Specifies how the row of a |
| public @interface | SecondaryRows
A grouping of |
| public @interface | SelectBeforeUpdate
Deprecated
since 6.2. Since Specifies that the current persistent state of a detached entity instance
should be fetched from the database when the entity is reattached using
org. is deprecated
org..
|
| public @interface | SoftDelete
Describes a soft-delete indicator mapping. |
| public @interface | SortComparator
Sort a |
| public @interface | SortNatural
Sort a
Sorting is performed in memory, by Java's |
| public @interface | Source
Deprecated
since 6.2. use Indicates the source of timestamps for an entity
version property of
type CurrentTimestamp instead
java.:
|
| public @interface | SQLDelete
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. |
| public @interface | SQLDeleteAll
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. |
| public @interface | SQLDeletes
A grouping of |
| public @interface | SqlFragmentAlias
Defines an interpolated alias occurring in a SQL filter condition. |
| public @interface | SQLInsert
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. |
| public @interface | SQLInserts
A grouping of |
| public @interface | SQLJoinTableRestriction
Specifies a restriction written in native SQL to add to the generated SQL when querying the join table of a collection. |
| public @interface | SQLOrder
Order a collection using an expression or list of expression written in native SQL. |
| public @interface | SQLRestriction
Specifies a restriction written in native SQL to add to the generated SQL for entities or collections. |
| public @interface | SQLSelect
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. This occurs when:
|
| public @interface | SQLUpdate
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. |
| public @interface | SQLUpdates
A grouping of |
| public @interface | Struct
Specifies the UDT (user defined type) name for the annotated embeddable type or embedded attribute. |
| public @interface | Subselect
Maps an immutable and read-only entity to a given SQL |
| public @interface | Synchronize
Specifies a table or tables that hold state mapped by the annotated entity or collection. |
| public @interface | Table
Deprecated
for removal since 6.2. The options available here are all now offered by other newer and better-designed
annotations in this package.
Complementary information for a table declared using the jakarta.,
or jakarta. annotation.
|
| public @interface | |
| public @interface | Target
Deprecated
since 6.2. use annotation members of JPA association mapping
annotations, for example,
Explicitly specifies the target entity type in an association,
avoiding reflection and generics resolution.
jakarta.
|
| public @interface | TenantId
Identifies a field of an entity that holds a tenant id in discriminator-based multitenancy. |
| public @interface | TimeZoneColumn
Specifies the mapped column for storing the time zone information,
for use in conjunction with |
| public @interface | TimeZoneStorage
Specifies how the time zone information of a persistent property or field should be persisted. |
| public @interface | |
| public @interface | TypeBinderType
Associates a user-defined annotation with a |
| public @interface | TypeRegistration
Registers a custom user type implementation to be used by default for all references to a particular class of basic type. |
| public @interface | TypeRegistrations
Grouping of |
| public @interface | UpdateTimestamp
Specifies that the annotated field of property is a generated update timestamp. |
| public @interface | UuidGenerator
Specifies that an entity identifier is generated as an IETF RFC 4122 UUID. |
| public @interface | ValueGenerationType
Meta-annotation used to mark another annotation as providing configuration for a custom value generation strategy. |
| public @interface | View
Maps an entity to a database view. |
| public @interface | Where
Deprecated
since 6.3. Use Specifies a restriction written in native SQL to add to the generated
SQL for entities or collections.
SQLRestriction
|
| public @interface | WhereJoinTable
Deprecated
since 6.3. Use Specifies a restriction written in native SQL to add to the generated SQL
when querying the join table
of a collection.
SQLJoinTableRestriction
|
| Modifier and Type | Class and Description |
|---|---|
| public class | |
| public class | QueryHints
Deprecated
since 6.0. Use List of hints that may be passed to AvailableHints instead
jakarta.
to control execution of a query.
|
| Modifier and Type | Enum and Description |
|---|---|
| public enum | CacheConcurrencyStrategy
Identifies policies for managing concurrent access to the shared second-level cache. |
| public enum | CacheModeType
Deprecated
since 6.2. use Enumerates the different interaction modes between the session
and the second-level Cache.
CacheMode or
jakarta. and
jakarta..
|
| public enum | CascadeType
Enumerates the persistence operations which may be cascaded from one entity instance to associated entity instances. |
| public enum | FetchMode
Enumerates methods for fetching an association from the database. |
| public enum | FlushModeType
Enumeration extending the JPA flush modes
with flush modes specific to Hibernate, and a "null" mode, |
| public enum | GenerationTime
Deprecated
since 6.2. use Represents a class of events involving interaction with the database
that causes generation of a new value.
EventType and EventTypeSets instead
|
| public enum | LazyCollectionOption
Deprecated
Enumerates the options for lazy loading of a
collection,
many to one association,
or many to many association.
|
| public enum | LazyToOneOption
Deprecated
since 6.2. since Enumerates the options for lazy loading of a
many to one
or one to one
association.
LazyToOne is deprecated, use
jakarta. instead
|
| public enum | NotFoundAction
Specifies how Hibernate should handle the case of an orphaned foreign key with no associated row in the referenced table. |
| public enum | OnDeleteAction
Enumerates the possible actions for the |
| public enum | OptimisticLockType
Enumerates the possible optimistic lock checking strategies. |
| public enum | PolymorphismType
Deprecated
since 6.2. since Specifies whether implicit polymorphism is enabled or disabled.
Polymorphism is deprecated
|
| public enum | ResultCheckStyle
Enumerates strategies for checking JDBC return codes for custom SQL DML queries. |
| public enum | SoftDeleteType
Enumeration of defines styles of soft-delete |
| public enum | SourceType
Specifies the source of a generated value, either the virtual machine, or the database. |
| public enum | TimeZoneStorageType
Describes the storage of timezone information for zoned datetime types,
in particular, for the types |