java-document the use of @Immutable and @Mutability with AttributeConverters
This commit is contained in:
parent
efd6c8c6fd
commit
0d9a32a9df
|
@ -15,29 +15,55 @@ import static java.lang.annotation.ElementType.*;
|
|||
/**
|
||||
* Marks an entity, collection, or attribute of an entity as immutable. The absence of this
|
||||
* annotation means the element is mutable.
|
||||
* <ul>
|
||||
* <li>
|
||||
* Changes made in memory to the state of an immutable entity are never synchronized to
|
||||
* the database. The changes are ignored, with no exception thrown. In a mapped inheritance
|
||||
* hierarchy, {@code @Immutable} may be applied only to the root entity, and is inherited
|
||||
* by entity subclasses. To make just one entity in the hierarchy immutable, annotate its
|
||||
* attributes individually.
|
||||
* </li>
|
||||
* <li>
|
||||
* An immutable collection may not be modified. A {@link org.hibernate.HibernateException}
|
||||
* is thrown if an element is added to or removed from the collection.
|
||||
* </li>
|
||||
* <li>
|
||||
* An immutable attribute is ignored by the dirty-checking process, and so the persistence
|
||||
* context does not need to keep track of its state. This may help reduce memory allocation.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Immutable entities</h3>
|
||||
* <p>
|
||||
* This annotation may also be used to mark a Java type handled by a JPA
|
||||
* Changes made in memory to the state of an immutable entity are never synchronized to
|
||||
* the database. The changes are ignored, with no exception thrown.
|
||||
* <p>
|
||||
* An immutable entity need not be dirty-checked, and so Hibernate does not need to
|
||||
* maintain a snapshot of its state. This may help reduce memory allocation.
|
||||
* Note that it's also possible to obtain an entity in read-only mode in a given session,
|
||||
* and this has similar benefits.
|
||||
* <p>
|
||||
* In a mapped inheritance hierarchy, {@code @Immutable} may be applied only to the root
|
||||
* entity, and is inherited by entity subclasses. To make just one entity in the hierarchy
|
||||
* immutable, annotate its attributes individually.
|
||||
*
|
||||
* <h3>Immutable basic-valued attributes</h3>
|
||||
* <p>
|
||||
* A mutable entity may have an immutable field or property.
|
||||
* <p>
|
||||
* An immutable attribute is ignored by the dirty-checking process, and so the persistence
|
||||
* context does not need to keep track of its state. This may help reduce memory allocation.
|
||||
*
|
||||
* <h3>Immutable collections</h3>
|
||||
* <p>
|
||||
* An immutable collection may not be modified.
|
||||
* <p>
|
||||
* A {@link org.hibernate.HibernateException} is thrown if an element is added to or
|
||||
* removed from the collection.
|
||||
*
|
||||
* <h3>Immutable for converters</h3>
|
||||
* <p>
|
||||
* {@code @Immutable} may also be used to mark a Java type handled by a JPA
|
||||
* {@link jakarta.persistence.AttributeConverter} as immutable, circumventing the need to treat
|
||||
* it as mutable.
|
||||
* <p>
|
||||
* Either:
|
||||
* <ul>
|
||||
* <li>annotate the Java type itself, or
|
||||
* <li>annotate the {@code AttributeConverter} class.
|
||||
* </ul>
|
||||
* <p>
|
||||
* This is not the same as marking the attribute {@code @Immutable}. A mutable attribute may
|
||||
* have a type whose values are immutable.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*
|
||||
* @see org.hibernate.Session#setDefaultReadOnly(boolean)
|
||||
* @see org.hibernate.Session#setReadOnly(Object, boolean)
|
||||
* @see org.hibernate.query.Query#setReadOnly(boolean)
|
||||
*/
|
||||
@Target({TYPE, METHOD, FIELD})
|
||||
@Retention( RetentionPolicy.RUNTIME )
|
||||
|
|
|
@ -20,42 +20,72 @@ import static java.lang.annotation.ElementType.TYPE;
|
|||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Specifies a {@link MutabilityPlan} for a basic value mapping.
|
||||
* Specifies a {@link MutabilityPlan} for a some sort of basic value mapping.
|
||||
*
|
||||
* <h3>Mutability for basic-typed attributes</h3>
|
||||
* <p>
|
||||
* For basic-valued attributes, {@code @Mutability} specifies the mutability
|
||||
* of the basic value type.
|
||||
* <p>
|
||||
* This is <em>not</em> the same as saying that the attribute itself is mutable
|
||||
* or immutable. A mutable attribute may have a type whose values are immutable.
|
||||
*
|
||||
* <h3>Mutability for values belonging to collections</h3>
|
||||
* <p>
|
||||
* Even collection elements, indexes, keys, and values have mutability
|
||||
* plans, and so this annotation may be applied to a collection-valued
|
||||
* attribute:
|
||||
* <ul>
|
||||
* <li>
|
||||
* When applied to a {@code Map}-valued attribute, describes
|
||||
* the {@code Map} value. Use {@link MapKeyMutability} to
|
||||
* describe the key instead.
|
||||
* When applied to a {@code Map}-valued attribute, it describes
|
||||
* the values of the map.
|
||||
* Use {@link MapKeyMutability} to describe the keys of the map.
|
||||
* </li>
|
||||
* <li>
|
||||
* When applied to a {@code List} of array-valued attribute,
|
||||
* describes the element.
|
||||
* </li>
|
||||
* <li>
|
||||
* When mapping an id-bag, describes the collection element.
|
||||
* When mapping an id-bag, it describes the elements of the bag.
|
||||
* Use {@link CollectionIdMutability} to describe the
|
||||
* {@link CollectionId}.
|
||||
* </li>
|
||||
* <li>
|
||||
* For other collection mappings, describes the elements.
|
||||
* For {@code List}-valued attributes, or for any other collection
|
||||
* mapping, it describes the elements of the collection.
|
||||
* </li>
|
||||
* <li>
|
||||
* For discriminated association mappings ({@link Any} and
|
||||
* {@link ManyToAny}), describes the discriminator value.
|
||||
* When applied to an array-valued attribute, it describes the
|
||||
* array element.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Resolved as a {@link org.hibernate.resource.beans.spi.ManagedBean}.
|
||||
* <p>
|
||||
* See <a href="package-summary.html#basic-value-mapping">basic-value-mapping</a>
|
||||
* for a high-level discussion of basic value mapping.
|
||||
* Again, this is not the same as saying that the collection itself is
|
||||
* mutable or immutable. One may add or remove immutable values to or
|
||||
* from a mutable collection.
|
||||
*
|
||||
* @apiNote Valid on {@link ElementType#TYPE} in very limited cases.
|
||||
* At the moment it is only supported on implementations of
|
||||
* {@link jakarta.persistence.AttributeConverter}.
|
||||
* <h3>Discriminated association mappings</h3>
|
||||
* <p>
|
||||
* For discriminated association mappings ({@link Any} or {@link ManyToAny}),
|
||||
* this annotation describes the mutability of the discriminator value.
|
||||
* <p>
|
||||
* This is not likely to be useful.
|
||||
*
|
||||
* <h3>Mutability for converters</h3>
|
||||
* <p>
|
||||
* {@code @Mutability} may also be used to specify the mutability of a
|
||||
* Java type handled by a JPA {@link jakarta.persistence.AttributeConverter},
|
||||
* circumventing the need to treat it as mutable.
|
||||
* <p>
|
||||
* Either:
|
||||
* <ul>
|
||||
* <li>annotate the Java type itself, or
|
||||
* <li>annotate the {@code AttributeConverter} class.
|
||||
* </ul>
|
||||
*
|
||||
* @apiNote Except for the case of converters, this annotation is not
|
||||
* usually applied to a {@linkplain ElementType#TYPE type}.
|
||||
*
|
||||
* @see Immutable
|
||||
* @see MutabilityPlan
|
||||
* @see <a href="package-summary.html#basic-value-mapping">Basic value type mappings</a>
|
||||
* @see org.hibernate.type
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
* The JPA specification perfectly nails many aspects of the O/R persistence problem, but
|
||||
* here we address some areas where it falls short.
|
||||
*
|
||||
* <h3 id="basic-value-mapping">Basic value type mappings</h3>
|
||||
*
|
||||
* <h3 id="basic-value-mapping">Basic types in JPA</h3>
|
||||
* <p>
|
||||
* 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>
|
||||
|
@ -82,6 +82,8 @@
|
|||
* JPA does provide {@linkplain jakarta.persistence.AttributeConverter 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.
|
||||
*
|
||||
* <h3 id="basic-value-mapping">Basic value type mappings</h3>
|
||||
* <p>
|
||||
* By contrast, Hibernate has an embarrassingly rich set of abstractions for modelling
|
||||
* basic types, which can be initially confusing.
|
||||
|
@ -93,29 +95,34 @@
|
|||
* Instead, a program should use either a "compositional" basic type, or in more extreme
|
||||
* cases, a {@code UserType}.
|
||||
* <ul>
|
||||
* <li>
|
||||
* <li><p>
|
||||
* 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.
|
||||
* <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>
|
||||
* <li><p>
|
||||
* A converter may be selected using the JPA {@link jakarta.persistence.Convert}
|
||||
* annotation, or it may be {@linkplain jakarta.persistence.Converter#autoApply()
|
||||
* applied implicitly}.
|
||||
* <li><p>
|
||||
* 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:
|
||||
* <li><p>
|
||||
* 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
|
||||
* <li><p>
|
||||
* 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.
|
||||
|
@ -124,14 +131,14 @@
|
|||
* 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.
|
||||
* <li>
|
||||
* <li><p>
|
||||
* Alternatively, a program may implement the {@link org.hibernate.usertype.UserType}
|
||||
* interface and associate it with a field or property explicitly using the
|
||||
* {@link org.hibernate.annotations.Type @Type} annotation, or implicitly using the
|
||||
* {@link org.hibernate.annotations.TypeRegistration @TypeRegistration} annotation.
|
||||
* <p>
|
||||
* There are some specialized flavors of the {@code @Type} annotation too.
|
||||
* </li>
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* These two approaches cannot be used together. A {@code UserType} always takes precedence
|
||||
|
@ -145,7 +152,7 @@
|
|||
* discussion.
|
||||
*
|
||||
* <h3 id="second-level-cache">Second level cache</h3>
|
||||
*
|
||||
* <p>
|
||||
* 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:
|
||||
* <ul>
|
||||
|
@ -177,7 +184,7 @@
|
|||
* advocated above.
|
||||
*
|
||||
* <h3 id="generated-values-natural-ids">Generated values</h3>
|
||||
*
|
||||
* <p>
|
||||
* JPA supports {@linkplain jakarta.persistence.GeneratedValue generated} identifiers,
|
||||
* that is, surrogate primary keys, with four useful built-in
|
||||
* {@linkplain jakarta.persistence.GenerationType types} of id generation.
|
||||
|
@ -212,7 +219,7 @@
|
|||
* {@link org.hibernate.annotations.GeneratedColumn}.
|
||||
*
|
||||
* <h3 id="natural-ids">Natural ids</h3>
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
|
@ -226,7 +233,7 @@
|
|||
* by natural id is a very common thing to do, and so the cache can often be helpful.
|
||||
*
|
||||
* <h3 id="filters">Filters</h3>
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
|
@ -246,7 +253,7 @@
|
|||
* particular session.
|
||||
*
|
||||
* <h3 id="dialect-specific-sql">Dialect-specific native SQL</h3>
|
||||
*
|
||||
* <p>
|
||||
* Many annotations in this package allow the specification of native SQL expressions or
|
||||
* even complete statements. For example:
|
||||
* <ul>
|
||||
|
|
Loading…
Reference in New Issue