more information about Types in javadoc

This commit is contained in:
Gavin 2022-12-30 11:29:08 +01:00
parent 1991e7d6a7
commit 31f11f4e3c
19 changed files with 253 additions and 69 deletions

View File

@ -55,6 +55,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* {@link jakarta.persistence.AttributeConverter}.
*
* @see Immutable
* @see MutabilityPlan
*
* @since 6.0
*

View File

@ -8,14 +8,79 @@
/**
* A set of mapping annotations which extend the O/R mapping annotations defined by JPA.
*
* <h2 id="basic-value-mapping">Basic value type mappings</h2>
* <h3 id="basic-value-mapping">Basic value type mappings</h3>
*
* A <em>basic type</em> handles the persistence of an attribute of an entity or embeddable
* object that is stored in exactly one database column.
* <p>
* JPA supports a very limited set of built-in {@linkplain jakarta.persistence.Basic basic}
* types, and provides only {@linkplain jakarta.persistence.AttributeConverter converters}
* as a solution when the built-in types are insufficient.
* types.
* <table style="border-spacing: 10px">
* <thead style="font-weight:bold">
* <tr>
* <td>Category</td><td>Package</td><td>Types</td>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>Primitive types</td>
* <td></td>
* <td>{@code boolean}, {@code int}, {@code double}, etc.</td>
* </tr>
* <tr>
* <td>Primitive wrappers</td>
* <td>{@code java.lang}</td>
* <td>{@code Boolean}, {@code Integer}, {@code Double}, etc.</td>
* </tr>
* <tr>
* <td>Strings</td><td>{@code java.lang}</td>
* <td>{@code String}</td>
* </tr>
* <tr>
* <td>Arbitrary-precision numeric types</td>
* <td>{@code java.math}</td><td>{@code BigInteger}, {@code BigDecimal}</td>
* </tr>
* <tr>
* <td>Date/time types</td><td>{@code java.time}</td>
* <td>{@code LocalDate}, {@code LocalTime}, {@code LocalDateTime}, {@code OffsetDateTime}, {@code Instant}</td>
* </tr>
* <tr>
* <td>Deprecated date/time types</td>
* <td>{@code java.util}</td>
* <td>{@code Date}, {@code Calendar}</td>
* </tr>
* <tr>
* <td>Deprecated JDBC date/time types</td>
* <td>{@code java.sql}</td>
* <td>{@code Date}, {@code Time}, {@code Timestamp}</td>
* </tr>
* <tr>
* <td>Binary and character arrays</td>
* <td></td>
* <td>{@code byte[]}, {@code char[]}</td>
* </tr>
* <tr>
* <td>UUIDs</td><td>{@code java.util}</td>
* <td>{@code UUID}</td>
* </tr>
* <tr>
* <td>Enumerated types</td>
* <td></td>
* <td>Any {@code enum}</td>
* </tr>
* <tr>
* <td>Serializable types</td>
* <td></td>
* <td>Any {@code java.io.Serializable}</td>
* </tr>
* </tbody>
* </table>
* <p>
* JPA provides only {@linkplain jakarta.persistence.AttributeConverter converters} as a
* solution when the built-in types are insufficient.
* <p>
* By contrast, Hibernate has an embarrassingly rich set of abstractions for modelling
* "basic" types, which can be initially confusing. Note that the venerable interface
* basic types, which can be initially confusing. Note that the venerable interface
* {@link org.hibernate.type.Type} abstracts over all sorts of field and property types,
* not only basic types. In modern Hibernate, programs should avoid directly implementing
* this interface.
@ -27,19 +92,30 @@
* A basic type is a composition of a {@link org.hibernate.type.descriptor.java.JavaType}
* with a {@link org.hibernate.type.descriptor.jdbc.JdbcType}, and possibly a JPA
* {@link jakarta.persistence.AttributeConverter}, and the process of composition is
* usually somewhat implicit. A program may influence the choice of {@code JavaType}
* or {@code JdbcType} using any of the following annotations:
* <ul>
* <li>{@link org.hibernate.annotations.JavaType}
* <li>{@link org.hibernate.annotations.JdbcType}
* <li>{@link org.hibernate.annotations.JdbcTypeCode}
* <li>{@link org.hibernate.annotations.Mutability}
* <li>{@link jakarta.persistence.Convert}
* <li>{@link jakarta.persistence.Lob}
* <li>{@link jakarta.persistence.Enumerated}
* <li>{@link jakarta.persistence.Temporal}
* <li>{@link org.hibernate.annotations.Nationalized}
* </ul>
* usually somewhat implicit.
* <ol>
* <li>A converter may be selected using the JPA {@link jakarta.persistence.Convert}
* annotation.
* <li>A {@code JavaType} or {@code JdbcType} may be indicated <em>explicitly</em>
* using the following annotations:
* <ul>
* <li>{@link org.hibernate.annotations.JavaType}
* <li>{@link org.hibernate.annotations.JdbcType}
* <li>{@link org.hibernate.annotations.JdbcTypeCode}
* </ul>
* <li>But these annotation also influence the choice:
* <ul>
* <li>{@link jakarta.persistence.Lob}
* <li>{@link jakarta.persistence.Enumerated}
* <li>{@link jakarta.persistence.Temporal}
* <li>{@link org.hibernate.annotations.Nationalized}
* </ul>
* <li>A compositional type mapping also comes with a
* {@link org.hibernate.type.descriptor.java.MutabilityPlan}, which is usually
* chosen by the {@code JavaType}, but which may be overridden using the
* {@link org.hibernate.annotations.Mutability} annotation.
* </ol>
* <p>
* Note that {@link org.hibernate.annotations.JavaType}, {@link org.hibernate.annotations.JdbcType},
* {@link org.hibernate.annotations.JdbcTypeCode} and {@link org.hibernate.annotations.Mutability}
* all come in specialized flavors for handling map keys, list indexes, and so on.
@ -55,10 +131,12 @@
* These two approaches cannot be used together. A {@code UserType} always takes precedence
* over the compositional approach.
* <p>
* Please see the <em>User Guide</em> or the package {@link org.hibernate.type} for a more
* in-depth discussion.
* Please see the <em>User Guide</em> or the package {@link org.hibernate.type} for further
* discussion. The packages {@link org.hibernate.type.descriptor.java} and
* {@link org.hibernate.type.descriptor.jdbc} contain the built-in implementations of
* {@code JavaType} and {@code JdbcType}, respectively.
*
* <h2 id="basic-value-mapping">Dialect-specific native SQL</h2>
* <h3 id="basic-value-mapping">Dialect-specific native SQL</h3>
*
* Many annotations in this package allow the specification of native SQL expressions or
* even complete statements. For example:

View File

@ -6,8 +6,11 @@
*/
/**
* Implements the SPI for basic-value conversions.
* Implements the SPI for basic-typed value conversions.
*
* @see org.hibernate.metamodel.model.convert.spi.BasicValueConverter
*/
@Incubating
package org.hibernate.metamodel.model.convert.internal;
import org.hibernate.Incubating;

View File

@ -6,7 +6,7 @@
*/
/**
* Support for basic-value conversions. The main contract is
* Support for basic-typed value conversions. The main contract is
* {@link org.hibernate.metamodel.model.convert.spi.BasicValueConverter}.
* <p>
* All basic value conversions are defined by this package including:
@ -17,4 +17,7 @@
* {@link org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter}
* </ul>
*/
@Incubating
package org.hibernate.metamodel.model.convert;
import org.hibernate.Incubating;

View File

@ -12,15 +12,15 @@ import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* Support for basic-value conversions.
* Support for {@linkplain org.hibernate.type basic-typed} value conversions.
* <p>
* Conversions might be determined by:
* <ul>
* <li>a custom JPA {@link jakarta.persistence.AttributeConverter}, or
* <li>implicitly, based on the Java type, for example, for Java {@code enum}s.
* </ul>
* @param <D> The Java type we can use to represent the domain (object) type
* @param <R> The Java type we can use to represent the relational type
* @param <D> The Java type we use to represent the domain (object) type
* @param <R> The Java type we use to represent the relational type
*
* @author Steve Ebersole
*/

View File

@ -6,24 +6,15 @@
*/
package org.hibernate.metamodel.model.convert.spi;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.hibernate.Remove;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.JdbcOperationQuery;
import org.hibernate.Incubating;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import static org.hibernate.metamodel.model.convert.internal.EnumHelper.getEnumeratedValues;
/**
* {@link BasicValueConverter} extension for enum-specific support
*
* @author Steve Ebersole
*/
@Incubating
public interface EnumValueConverter<O extends Enum<O>, R> extends BasicValueConverter<O,R> {
@Override
EnumJavaType<O> getDomainJavaType();

View File

@ -8,6 +8,7 @@ package org.hibernate.metamodel.model.convert.spi;
import jakarta.persistence.AttributeConverter;
import org.hibernate.Incubating;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.type.descriptor.java.JavaType;
@ -16,6 +17,7 @@ import org.hibernate.type.descriptor.java.JavaType;
*
* @author Steve Ebersole
*/
@Incubating
public interface JpaAttributeConverter<O,R> extends BasicValueConverter<O,R> {
JavaType<? extends AttributeConverter<O,R>> getConverterJavaType();

View File

@ -6,8 +6,11 @@
*/
/**
* An SPI for basic-value conversions.
* An SPI for basic-typed value conversions.
*
* @see org.hibernate.metamodel.model.convert.spi.BasicValueConverter
*/
@Incubating
package org.hibernate.metamodel.model.convert.spi;
import org.hibernate.Incubating;

View File

@ -13,13 +13,42 @@ import org.hibernate.SharedSessionContract;
/**
* Describes the mutability aspects of a given Java type.
* <p>
* The term "mutability" refers to the fact that, generally speaking, the
* aspects described by this contract are determined by whether the Java
* type's internal state is mutable or immutable. For example, for an
* immutable Java class, {@link #deepCopy(Object)} may simply return its
* argument.
* Mutable values require special handling that is not necessary for
* immutable values:
* <ul>
* <li>a mutable value must be {@linkplain #deepCopy(Object) cloned} when
* taking a "snapshot" of the state of an entity for dirty-checking,
* and
* <li>a mutable value requires more careful handling when the entity is
* {@linkplain #disassemble(Object, SharedSessionContract) disassembled}
* for storage in destructured form in the second-level cache.
* </ul>
* <p>
* Neither is a requirement for correctness when dealing with an immutable
* object. But there might be other reasons why an immutable object requires
* custom implementations of {@link #disassemble} and {@link #assemble}.
* <p>
* For example:
* <ul>
* <li>if the object is not serializable, we might convert it to a serializable
* format,
* <li>if the object hold a reference to an entity, we must replace that
* reference with an identifier, or
* <li>if the object hold a reference to some heavyweight resource, we must
* release it.
* </ul>
* <p>
* For an immutable type, it's not usually necessary to do anything special
* in {@link #deepCopy}. The method can simply return its argument.
*
* @apiNote The term "mutability" refers to the fact that, in general,
* the aspects of the Java type described by this contract are
* determined by whether the Java type has mutable internal
* state.
*
* @author Steve Ebersole
*
* @see org.hibernate.annotations.Mutability
*/
public interface MutabilityPlan<T> extends Serializable {
/**
@ -40,9 +69,9 @@ public interface MutabilityPlan<T> extends Serializable {
/**
* Return a disassembled representation of the value.
*
* <p>
* Called before storing a value in the second-level cache.
*
* <p>
* Complementary to {@link #assemble}.
*
* @see #assemble
@ -51,9 +80,9 @@ public interface MutabilityPlan<T> extends Serializable {
/**
* Assemble a previously {@linkplain #disassemble disassembled} value.
*
* <p>
* Called after reading a value from the second level cache.
*
* <p>
* Complementary to {@link #disassemble}.
*
* @see #disassemble

View File

@ -9,5 +9,19 @@
* Integrates a range of types defined by the JDK with the type system
* of Hibernate. Each Java type is described by an implementation of
* {@link org.hibernate.type.descriptor.java.JavaType}.
* <p>
* Certain important aspects related to the mutability or immutability
* of a Java type are described by an associated
* {@link org.hibernate.type.descriptor.java.MutabilityPlan}. In particular,
* the right {@code MutabilityPlan} allows for correct dirty-checking and
* destructured storage of values in the second-level cache.
* <p>
* See {@linkplain org.hibernate.type this discussion} of the roles
* {@code JavaType} and {@code MutabilityPlan} play in basic type mappings.
*
* @see org.hibernate.type
*
* @see org.hibernate.type.descriptor.java.JavaType
* @see org.hibernate.type.descriptor.java.MutabilityPlan
*/
package org.hibernate.type.descriptor.java;

View File

@ -19,18 +19,23 @@ import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaType;
/**
* Descriptor for binding objects
* Descriptor for binding objects using any {@linkplain Types JDBC type code}.
*
* @author Steve Ebersole
*/
public class ObjectJdbcType implements JdbcType {
/**
* Singleton access
* An instance for the JDBC type code {@link Types#JAVA_OBJECT JAVA_OBJECT}.
*/
public static final ObjectJdbcType INSTANCE = new ObjectJdbcType( Types.JAVA_OBJECT );
private final int jdbcTypeCode;
/**
* Construct an instance for handling the given {@linkplain Types JDBC type code}.
*
* @param jdbcTypeCode any type code defined by {@link Types}.
*/
public ObjectJdbcType(int jdbcTypeCode) {
this.jdbcTypeCode = jdbcTypeCode;
}
@ -42,7 +47,7 @@ public class ObjectJdbcType implements JdbcType {
@Override
public String toString() {
return "ObjectSqlTypeDescriptor(" + jdbcTypeCode + ")";
return "ObjectTypeDescriptor(" + jdbcTypeCode + ")";
}
@Override

View File

@ -22,7 +22,7 @@ import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaType;
/**
* Specialized type mapping for {@code SQLXML} and the XML SQL data type.
* Specialized type mapping for {@link SQLXML} and the XML SQL data type.
*
* @author Christian Beikov
*/

View File

@ -10,23 +10,30 @@
* java.sql.Types SQL data types}. Each JDBC type is described by an implementation
* of {@link org.hibernate.type.descriptor.jdbc.JdbcType}.
* <p>
* See {@linkplain org.hibernate.type this discussion} of the role {@code JdbcType}
* plays in basic type mappings.
* <p>
* We omit certain JDBC types here solely because Hibernate does not use them itself,
* not due to any inability to provide proper descriptors for them. Known omissions
* include:
* not due to any inability to provide proper descriptors for them. There are no
* descriptors for:
* <ul>
* <li>{@link java.sql.Types#DATALINK DATALINK}</li>
* <li>{@link java.sql.Types#DISTINCT DISTINCT}</li>
* <li>{@link java.sql.Types#STRUCT STRUCT}</li>
* <li>{@link java.sql.Types#ROWID ROWID}</li>
* <li>{@link java.sql.Types#REF REF}</li>
* <li>{@link java.sql.Types#JAVA_OBJECT JAVA_OBJECT}</li>
* <li>{@link java.sql.Types#REF_CURSOR REF_CURSOR}</li>
* </ul>
* <p>
* Nor is there a generic descriptor for {@link java.sql.Types#STRUCT STRUCT} defined
* in this package, but dialect-specific implementations are provided elsewhere.
* <p>
* On the other hand, we actually <em>extend</em> the set of JDBC types by enumerating
* additional types in {@link org.hibernate.type.SqlTypes}.
* <p>
* See <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/mapping.html#996857">http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/mapping.html#996857</a>
* for more information.
*
* @see org.hibernate.type.descriptor.jdbc.JdbcType
* @see org.hibernate.type
* @see java.sql.Types
* @see org.hibernate.type.SqlTypes
* @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/mapping.html">Mapping SQL and Java Types</a>
*/
package org.hibernate.type.descriptor.jdbc;

View File

@ -8,7 +8,7 @@
/**
* Contracts for reading and writing values to and from JDBC.
* <p>
* Used by implementations of {@link org.hibernate.type.descriptor.jdbc.JdbcType}
* Used by implementations of {@link org.hibernate.type.descriptor.jdbc.JdbcType}.
*
* @see org.hibernate.type.descriptor.ValueBinder
* @see org.hibernate.type.descriptor.ValueExtractor

View File

@ -7,12 +7,22 @@
/**
* A Hibernate {@link org.hibernate.type.Type} is a strategy for mapping a Java
* property type to a JDBC type or types. In modern Hibernate, {@code Type} itself
* is now of receding importance, and we prefer to work directly with the combination
* of:
* property type to a JDBC type or types. Every persistent attribute of an entity
* or embeddable object has a {@code org.hibernate.type.Type}.
* <p>
* On the other hand, in modern Hibernate, {@code Type} itself is of receding
* importance to application developers, though it remains a very important
* internal abstraction.
*
* <h3>Basic types</h3>
*
* For {@linkplain jakarta.persistence.Basic basic} types, we prefer to model the
* type mapping in terms the combination of:
* <ul>
* <li>a {@link org.hibernate.type.descriptor.java.JavaType}, with
* <li>a {@link org.hibernate.type.descriptor.jdbc.JdbcType}.
* <li>a {@link org.hibernate.type.descriptor.jdbc.JdbcType}, and,
* <li>possibly, a {@linkplain org.hibernate.metamodel.model.convert.spi.BasicValueConverter
* converter}, though this is not usually needed.
* </ul>
* <p>
* A {@code JdbcType} is able to read and write a single Java type to one, or
@ -32,9 +42,30 @@
* This approach provides quite some flexibility in allowing a given Java type to
* map to a range of JDBC types. However, when the built-in conversions don't handle
* a particular mapping, a
* {@link org.hibernate.metamodel.model.convert.spi.BasicValueConverter} may assist
* in the conversion process. For example, a JPA
* {@linkplain org.hibernate.metamodel.model.convert.spi.BasicValueConverter converter}
* may assist in the conversion process. For example, a JPA
* {@link jakarta.persistence.AttributeConverter} might be provided.
* <p>
* A {@code JavaType} comes with a built-in
* {@link org.hibernate.type.descriptor.java.MutabilityPlan}, but this may be
* overridden when types are composed.
* <p>
* See {@link org.hibernate.annotations} for information on how to influence basic
* type mappings using annotations.
*
* <h3>Custom types</h3>
*
* The package {@link org.hibernate.usertype} provides a way for application developers
* to define new types without being exposed to the full complexity of the {@code Type}
* framework defined in this package.
* <ul>
* <li>A {@link org.hibernate.usertype.UserType} may be used to define single-column
* type mappings, and thus competes with the "compositional" approach to basic type
* mappings described above.
* <li>On the other hand, a {@link org.hibernate.usertype.CompositeUserType} defines a
* way to handle multi-column type mappings, and is a much more flexible form of
* {@link jakarta.persistence.Embeddable} object mapping.
* </ul>
*
* @see org.hibernate.type.Type
* @see org.hibernate.type.SqlTypes

View File

@ -23,16 +23,16 @@ import org.hibernate.metamodel.spi.ValueAccess;
* <p>
* A value type managed by a {@code CompositeUserType} may be used in
* almost every way that a regular embeddable type may be used. It may
* even contain many-to-one associations.
* even contain {@linkplain jakarta.persistence.ManyToOne many to one}
* associations.
* <p>
* To "map" the attributes of a composite custom type, each
* {@code CompositeUserType} provides a {@linkplain #embeddable()
* regular embeddable class} with the same logical structure as the
* {@linkplain #returnedClass() value type managed by the custom
* type}.
* {@linkplain #returnedClass() value type managed by the custom type}.
* <p>
* For example, if we implement a {@code CompositeUserType} for a
* {@code MonetaryAmount} class, we would also provide a
* For example, if we were to implement a {@code CompositeUserType}
* for a {@code MonetaryAmount} class, we would also provide a
* {@code MonetaryAmountEmbeddable} class with a field for each
* logical persistent attribute of the custom type. Of course,
* {@code MonetaryAmountEmbeddable} is never instantiated at runtime,

View File

@ -7,5 +7,12 @@
/**
* An API for user-defined custom types.
* <p>
* A custom type might map a {@linkplain org.hibernate.usertype.UserType single column},
* or it might map {@linkplain org.hibernate.usertype.CompositeUserType multiple columns}.
*
* @see org.hibernate.usertype.UserType
* @see org.hibernate.usertype.CompositeUserType
* @see org.hibernate.type
*/
package org.hibernate.usertype;

View File

@ -89,6 +89,11 @@
{@link org.hibernate.boot.model.naming} allows the quantity of repetitive O/R mapping
metadata to be minimized via the use of naming strategies,
</li>
<li>
{@link org.hibernate.type.descriptor.jdbc} and {@link org.hibernate.type.descriptor.java}
contain the built-in {@code JdbcType}s and {@code JavaType}s for "compositional" basic
attribute type mappings,
</li>
<li>
{@link org.hibernate.usertype} defines support for user-defined custom attribute types,
</li>

View File

@ -89,6 +89,11 @@
{@link org.hibernate.boot.model.naming} allows the quantity of repetitive O/R mapping
metadata to be minimized via the use of naming strategies,
</li>
<li>
{@link org.hibernate.type.descriptor.jdbc} and {@link org.hibernate.type.descriptor.java}
contain the built-in {@code JdbcType}s and {@code JavaType}s for "compositional" basic
attribute type mappings,
</li>
<li>
{@link org.hibernate.usertype} defines support for user-defined custom attribute types,
</li>