HHH-6970 - Expand notion of "natural id mutability" to ternary value

This commit is contained in:
Steve Ebersole 2012-01-13 16:51:01 -06:00
parent 0c80b409a1
commit 57e9b48587
6 changed files with 103 additions and 6 deletions

View File

@ -0,0 +1,54 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate;
/**
* Possible values regarding the mutability of a natural id.
*
* @author Steve Ebersole
*/
public enum NaturalIdMutability {
/**
* The natural id is mutable. Hibernate will write changes in the natural id value when flushing updates to the
* the entity to the database. Also, it will invalidate any caching when such a change is detected.
*/
MUTABLE,
/**
* The natural id is immutable. Hibernate will ignore any changes in the natural id value when flushing updates
* to the entity to the database. Additionally Hibernate <b>will not</b> check with the database to check if the
* natural id values change there. Essentially the user is assuring Hibernate that the values will not change.
*/
IMMUTABLE,
/**
* The natural id is immutable. Hibernate will ignore any changes in the natural id value when flushing updates
* to the entity to the database. However, Hibernate <b>will</b> check with the database to check if the natural
* id values change there. This will ensure caching gets invalidated if the natural id value is changed in the
* database (outside of this Hibernate SessionFactory).
*
* Note however that frequently changing natural ids are really not natural ids and should really not be mapped
* as such. The overhead of maintaining caching of natural ids in these cases is far greater than the benefit
* from such caching. In such cases, a database index is a much better solution.
*/
IMMUTABLE_CHECKED
}

View File

@ -22,24 +22,41 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.hibernate.NaturalIdMutability;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* This specifies that a property is part of the natural id of the entity.
*
* @author Nicol<EFBFBD>s Lichtmaier
* @author Steve Ebersole
*/
@Target( { METHOD, FIELD } )
@Retention( RUNTIME )
public @interface NaturalId {
/**
* If this natural id component is mutable or not.
* @deprecated Use {@link #mutability()} instead. For {@code mutable == false} (the default) use
* {@link NaturalIdMutability#IMMUTABLE_CHECKED}; for {@code mutable == true} use
* {@link NaturalIdMutability#MUTABLE}.
*
* Note however the difference between {@link NaturalIdMutability#IMMUTABLE_CHECKED} which mimics the old behavior
* of {@code mutable == false} and the new behavior available via {@link NaturalIdMutability#IMMUTABLE}
*/
@Deprecated
@SuppressWarnings( {"JavaDoc"})
boolean mutable() default false;
/**
* The mutability behavior of this natural id
*
* @return The mutability behavior.
*/
NaturalIdMutability mutability();
}

View File

@ -104,6 +104,7 @@ public class BinderHelper {
clone.setName( property.getName() );
clone.setNodeName( property.getNodeName() );
clone.setNaturalIdentifier( property.isNaturalIdentifier() );
clone.setNaturalIdMutability( property.getNaturalIdMutability() );
clone.setOptimisticLocked( property.isOptimisticLocked() );
clone.setOptional( property.isOptional() );
clone.setPersistentClass( property.getPersistentClass() );

View File

@ -40,6 +40,7 @@ import org.hibernate.EntityMode;
import org.hibernate.FetchMode;
import org.hibernate.FlushMode;
import org.hibernate.MappingException;
import org.hibernate.NaturalIdMutability;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.FilterDefinition;
@ -2223,8 +2224,15 @@ public final class HbmBinder {
if ( value != null ) {
Property property = createProperty( value, propertyName, persistentClass
.getClassName(), subnode, mappings, inheritedMetas );
if ( !mutable ) property.setUpdateable(false);
if ( naturalId ) property.setNaturalIdentifier(true);
if ( !mutable ) {
property.setUpdateable(false);
}
if ( naturalId ) {
property.setNaturalIdentifier(true);
property.setNaturalIdMutability(
mutable ? NaturalIdMutability.MUTABLE : NaturalIdMutability.IMMUTABLE_CHECKED
);
}
persistentClass.addProperty( property );
if ( uniqueKey!=null ) uniqueKey.addColumns( property.getColumnIterator() );
}

View File

@ -30,6 +30,7 @@ import javax.persistence.Id;
import org.jboss.logging.Logger;
import org.hibernate.AnnotationException;
import org.hibernate.NaturalIdMutability;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.Immutable;
@ -287,10 +288,17 @@ public class PropertyBinder {
property.getAnnotation( NaturalId.class ) :
null;
if ( naturalId != null ) {
if ( !naturalId.mutable() ) {
NaturalIdMutability mutability = naturalId.mutability();
if ( mutability == null ) {
mutability = naturalId.mutable()
? NaturalIdMutability.MUTABLE
: NaturalIdMutability.IMMUTABLE_CHECKED;
}
if ( mutability != NaturalIdMutability.MUTABLE ) {
updatable = false;
}
prop.setNaturalIdentifier( true );
prop.setNaturalIdMutability( mutability );
}
prop.setInsertable( insertable );
prop.setUpdateable( updatable );

View File

@ -28,6 +28,7 @@ import java.util.StringTokenizer;
import org.hibernate.EntityMode;
import org.hibernate.MappingException;
import org.hibernate.NaturalIdMutability;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.Mapping;
@ -45,7 +46,6 @@ import org.hibernate.type.Type;
* @author Gavin King
*/
public class Property implements Serializable, MetaAttributable {
private String name;
private Value value;
private String cascade;
@ -61,6 +61,7 @@ public class Property implements Serializable, MetaAttributable {
private java.util.Map metaAttributes;
private PersistentClass persistentClass;
private boolean naturalIdentifier;
private NaturalIdMutability naturalIdMutability;
public boolean isBackRef() {
return false;
@ -315,4 +316,12 @@ public class Property implements Serializable, MetaAttributable {
public void setNaturalIdentifier(boolean naturalIdentifier) {
this.naturalIdentifier = naturalIdentifier;
}
public NaturalIdMutability getNaturalIdMutability() {
return naturalIdMutability;
}
public void setNaturalIdMutability(NaturalIdMutability naturalIdMutability) {
this.naturalIdMutability = naturalIdMutability;
}
}