clarify some javadoc for @Immutable and optimistic locking stuff
This commit is contained in:
parent
3c535c544f
commit
bdc67f81b1
|
@ -13,13 +13,15 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
/**
|
||||
* Marks an entity, collection, or attribute as immutable. The absence of this annotation
|
||||
* means the element is mutable.
|
||||
* 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.
|
||||
* 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}
|
||||
|
|
|
@ -12,11 +12,14 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Specifies whether updating the annotated attribute should trigger an increment
|
||||
* to the {@link jakarta.persistence.Version version} of the entity instance.
|
||||
* Specifies whether mutating the annotated attribute should trigger an increment
|
||||
* to the {@link jakarta.persistence.Version version} of the entity instance. Or,
|
||||
* if {@link OptimisticLockType#ALL} or {@link OptimisticLockType#DIRTY} are used,
|
||||
* specifies whether the attribute should be included or excluded from the list of
|
||||
* checked attributes.
|
||||
* <p>
|
||||
* If this annotation is not present, updating an attribute does cause the version
|
||||
* to be incremented.
|
||||
* If this annotation is not present, mutating an attribute <em>does</em> cause the
|
||||
* version to be incremented.
|
||||
*
|
||||
* @author Logi Ragnarsson
|
||||
*/
|
||||
|
|
|
@ -14,7 +14,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
|
||||
/**
|
||||
* Specifies how optimistic lock checking works for the annotated entity.
|
||||
* We may detect that an optimistic lock has failed by checking either:
|
||||
* Optimistic lock checking may detect that an optimistic lock has failed,
|
||||
* and that the transaction should be aborted, by comparing either:
|
||||
* <ul>
|
||||
* <li>the {@linkplain OptimisticLockType#VERSION version or timestamp},
|
||||
* <li>the {@linkplain OptimisticLockType#DIRTY dirty fields} of the
|
||||
|
@ -23,14 +24,22 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
* </ul>
|
||||
* An optimistic lock is usually checked by including a restriction in a
|
||||
* SQL {@code update} or {@code delete} statement. If the database reports
|
||||
* that zero rows were updated, we may infer that another transaction has
|
||||
* already updated or deleted the row, and report the {@linkplain
|
||||
* jakarta.persistence.OptimisticLockException failure} of the optimistic
|
||||
* lock.
|
||||
* that zero rows were updated, it is inferred that another transaction
|
||||
* has already updated or deleted the row, and the failure of the optimistic
|
||||
* lock is reported via an {@link jakarta.persistence.OptimisticLockException}.
|
||||
* <p>
|
||||
* In an inheritance hierarchy, this annotation may only be applied to the
|
||||
* root entity, since the optimistic lock checking strategy is inherited
|
||||
* by entity subclasses.
|
||||
* <p>
|
||||
* To exclude a particular attribute from optimistic locking, annotate the
|
||||
* attribute {@link OptimisticLock @OptimisticLock(excluded=true)}. Then:
|
||||
* <ul>
|
||||
* <li>changes to that attribute will never trigger a version increment, and
|
||||
* <li>the attribute will not be included in the list of fields checked fields
|
||||
* when {@link OptimisticLockType#ALL} or {@link OptimisticLockType#DIRTY}
|
||||
* is used.
|
||||
* </ul>
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
|
|
|
@ -381,8 +381,8 @@ public class PropertyBinder {
|
|||
return property;
|
||||
}
|
||||
|
||||
private void handleNaturalId(Property prop) {
|
||||
final NaturalId naturalId = property.getAnnotation(NaturalId.class);
|
||||
private void handleNaturalId(Property property) {
|
||||
final NaturalId naturalId = this.property.getAnnotation(NaturalId.class);
|
||||
if ( naturalId != null ) {
|
||||
if ( !entityBinder.isRootEntity() ) {
|
||||
throw new AnnotationException( "Property '" + qualify( holder.getPath(), name )
|
||||
|
@ -392,27 +392,27 @@ public class PropertyBinder {
|
|||
if ( !naturalId.mutable() ) {
|
||||
updatable = false;
|
||||
}
|
||||
prop.setNaturalIdentifier( true );
|
||||
property.setNaturalIdentifier( true );
|
||||
}
|
||||
}
|
||||
|
||||
private void inferOptimisticLocking(Property prop) {
|
||||
private void inferOptimisticLocking(Property property) {
|
||||
// this is already handled for collections in CollectionBinder...
|
||||
if ( value instanceof Collection ) {
|
||||
prop.setOptimisticLocked( ((Collection) value).isOptimisticLocked() );
|
||||
property.setOptimisticLocked( ((Collection) value).isOptimisticLocked() );
|
||||
}
|
||||
else if ( property != null && property.isAnnotationPresent(OptimisticLock.class) ) {
|
||||
final OptimisticLock lockAnn = property.getAnnotation(OptimisticLock.class);
|
||||
validateOptimisticLock(lockAnn);
|
||||
prop.setOptimisticLocked( !lockAnn.excluded() );
|
||||
else if ( this.property != null && this.property.isAnnotationPresent(OptimisticLock.class) ) {
|
||||
final OptimisticLock optimisticLock = this.property.getAnnotation(OptimisticLock.class);
|
||||
validateOptimisticLock( optimisticLock );
|
||||
property.setOptimisticLocked( !optimisticLock.excluded() );
|
||||
}
|
||||
else {
|
||||
prop.setOptimisticLocked( !isToOneValue(value) || insertable ); // && updatable as well???
|
||||
property.setOptimisticLocked( !isToOneValue(value) || insertable ); // && updatable as well???
|
||||
}
|
||||
}
|
||||
|
||||
private void validateOptimisticLock(OptimisticLock lockAnn) {
|
||||
if ( lockAnn.excluded() ) {
|
||||
private void validateOptimisticLock(OptimisticLock optimisticLock) {
|
||||
if ( optimisticLock.excluded() ) {
|
||||
if ( property.isAnnotationPresent(Version.class) ) {
|
||||
throw new AnnotationException("Property '" + qualify( holder.getPath(), name )
|
||||
+ "' is annotated '@OptimisticLock(excluded=true)' and '@Version'" );
|
||||
|
|
Loading…
Reference in New Issue