FileDocCategorySizeDatePackage
EntityMetamodel.javaAPI DocHibernate 3.2.518388Fri Jan 19 05:55:08 GMT 2007org.hibernate.tuple.entity

EntityMetamodel

public class EntityMetamodel extends Object implements Serializable
Centralizes metamodel information about an entity.
author
Steve Ebersole

Fields Summary
private static final Log
log
private static final int
NO_VERSION_INDX
private final org.hibernate.engine.SessionFactoryImplementor
sessionFactory
private final String
name
private final String
rootName
private final org.hibernate.type.EntityType
entityType
private final org.hibernate.tuple.IdentifierProperty
identifierProperty
private final boolean
versioned
private final int
propertySpan
private final int
versionPropertyIndex
private final org.hibernate.tuple.StandardProperty[]
properties
private final String[]
propertyNames
private final org.hibernate.type.Type[]
propertyTypes
private final boolean[]
propertyLaziness
private final boolean[]
propertyUpdateability
private final boolean[]
nonlazyPropertyUpdateability
private final boolean[]
propertyCheckability
private final boolean[]
propertyInsertability
private final org.hibernate.engine.ValueInclusion[]
insertInclusions
private final org.hibernate.engine.ValueInclusion[]
updateInclusions
private final boolean[]
propertyNullability
private final boolean[]
propertyVersionability
private final org.hibernate.engine.CascadeStyle[]
cascadeStyles
private final boolean
hasInsertGeneratedValues
private final boolean
hasUpdateGeneratedValues
private final Map
propertyIndexes
private final boolean
hasCollections
private final boolean
hasMutableProperties
private final boolean
hasLazyProperties
private final boolean
hasNonIdentifierPropertyNamedId
private final int[]
naturalIdPropertyNumbers
private boolean
lazy
private final boolean
hasCascades
private final boolean
mutable
private final boolean
isAbstract
private final boolean
selectBeforeUpdate
private final boolean
dynamicUpdate
private final boolean
dynamicInsert
private final int
optimisticLockMode
private final boolean
polymorphic
private final String
superclass
private final boolean
explicitPolymorphism
private final boolean
inherited
private final boolean
hasSubclasses
private final Set
subclassEntityNames
private final EntityEntityModeToTuplizerMapping
tuplizerMapping
Constructors Summary
public EntityMetamodel(org.hibernate.mapping.PersistentClass persistentClass, org.hibernate.engine.SessionFactoryImplementor sessionFactory)

		this.sessionFactory = sessionFactory;

		name = persistentClass.getEntityName();
		rootName = persistentClass.getRootClass().getEntityName();
		entityType = TypeFactory.manyToOne( name );

		identifierProperty = PropertyFactory.buildIdentifierProperty(
		        persistentClass,
		        sessionFactory.getIdentifierGenerator( rootName )
			);

		versioned = persistentClass.isVersioned();

		boolean lazyAvailable = persistentClass.hasPojoRepresentation() &&
		                        FieldInterceptionHelper.isInstrumented( persistentClass.getMappedClass() );
		boolean hasLazy = false;

		propertySpan = persistentClass.getPropertyClosureSpan();
		properties = new StandardProperty[propertySpan];
		List naturalIdNumbers = new ArrayList();
		// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		propertyNames = new String[propertySpan];
		propertyTypes = new Type[propertySpan];
		propertyUpdateability = new boolean[propertySpan];
		propertyInsertability = new boolean[propertySpan];
		insertInclusions = new ValueInclusion[propertySpan];
		updateInclusions = new ValueInclusion[propertySpan];
		nonlazyPropertyUpdateability = new boolean[propertySpan];
		propertyCheckability = new boolean[propertySpan];
		propertyNullability = new boolean[propertySpan];
		propertyVersionability = new boolean[propertySpan];
		propertyLaziness = new boolean[propertySpan];
		cascadeStyles = new CascadeStyle[propertySpan];
		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


		Iterator iter = persistentClass.getPropertyClosureIterator();
		int i = 0;
		int tempVersionProperty = NO_VERSION_INDX;
		boolean foundCascade = false;
		boolean foundCollection = false;
		boolean foundMutable = false;
		boolean foundNonIdentifierPropertyNamedId = false;
		boolean foundInsertGeneratedValue = false;
		boolean foundUpdateGeneratedValue = false;

		while ( iter.hasNext() ) {
			Property prop = ( Property ) iter.next();

			if ( prop == persistentClass.getVersion() ) {
				tempVersionProperty = i;
				properties[i] = PropertyFactory.buildVersionProperty( prop, lazyAvailable );
			}
			else {
				properties[i] = PropertyFactory.buildStandardProperty( prop, lazyAvailable );
			}

			if ( prop.isNaturalIdentifier() ) {
				naturalIdNumbers.add( new Integer(i) );
			}

			if ( "id".equals( prop.getName() ) ) {
				foundNonIdentifierPropertyNamedId = true;
			}

			// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			boolean lazy = prop.isLazy() && lazyAvailable;
			if ( lazy ) hasLazy = true;
			propertyLaziness[i] = lazy;

			propertyNames[i] = properties[i].getName();
			propertyTypes[i] = properties[i].getType();
			propertyNullability[i] = properties[i].isNullable();
			propertyUpdateability[i] = properties[i].isUpdateable();
			propertyInsertability[i] = properties[i].isInsertable();
			insertInclusions[i] = determineInsertValueGenerationType( prop, properties[i] );
			updateInclusions[i] = determineUpdateValueGenerationType( prop, properties[i] );
			propertyVersionability[i] = properties[i].isVersionable();
			nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy;
			propertyCheckability[i] = propertyUpdateability[i] ||
					( propertyTypes[i].isAssociationType() && ( (AssociationType) propertyTypes[i] ).isAlwaysDirtyChecked() );

			cascadeStyles[i] = properties[i].getCascadeStyle();
			// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			if ( properties[i].isLazy() ) {
				hasLazy = true;
			}

			if ( properties[i].getCascadeStyle() != CascadeStyle.NONE ) {
				foundCascade = true;
			}

			if ( indicatesCollection( properties[i].getType() ) ) {
				foundCollection = true;
			}

			if ( propertyTypes[i].isMutable() && propertyCheckability[i] ) {
				foundMutable = true;
			}

			if ( insertInclusions[i] != ValueInclusion.NONE ) {
				foundInsertGeneratedValue = true;
			}

			if ( updateInclusions[i] != ValueInclusion.NONE ) {
				foundUpdateGeneratedValue = true;
			}

			mapPropertyToIndex(prop, i);
			i++;
		}

		if (naturalIdNumbers.size()==0) {
			naturalIdPropertyNumbers = null;
		}
		else {
			naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
		}

		hasInsertGeneratedValues = foundInsertGeneratedValue;
		hasUpdateGeneratedValues = foundUpdateGeneratedValue;

		hasCascades = foundCascade;
		hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;
		versionPropertyIndex = tempVersionProperty;
		hasLazyProperties = hasLazy;
		if ( hasLazyProperties ) {
			log.info( "lazy property fetching available for: " + name );
		}

		lazy = persistentClass.isLazy() && (
				// TODO: this disables laziness even in non-pojo entity modes:
				!persistentClass.hasPojoRepresentation() ||
				!ReflectHelper.isFinalClass( persistentClass.getProxyInterface() )
		);
		mutable = persistentClass.isMutable();
		if ( persistentClass.isAbstract() == null ) {
			// legacy behavior (with no abstract attribute specified)
			isAbstract = persistentClass.hasPojoRepresentation() &&
			             ReflectHelper.isAbstractClass( persistentClass.getMappedClass() );
		}
		else {
			isAbstract = persistentClass.isAbstract().booleanValue();
			if ( !isAbstract && persistentClass.hasPojoRepresentation() &&
			     ReflectHelper.isAbstractClass( persistentClass.getMappedClass() ) ) {
				log.warn( "entity [" + name + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names" );
			}
		}
		selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate();
		dynamicUpdate = persistentClass.useDynamicUpdate();
		dynamicInsert = persistentClass.useDynamicInsert();

		polymorphic = persistentClass.isPolymorphic();
		explicitPolymorphism = persistentClass.isExplicitPolymorphism();
		inherited = persistentClass.isInherited();
		superclass = inherited ?
				persistentClass.getSuperclass().getEntityName() :
				null;
		hasSubclasses = persistentClass.hasSubclasses();

		optimisticLockMode = persistentClass.getOptimisticLockMode();
		if ( optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION && !dynamicUpdate ) {
			throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name );
		}
		if ( versionPropertyIndex != NO_VERSION_INDX && optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION ) {
			throw new MappingException( "version and optimistic-lock=all|dirty are not a valid combination : " + name );
		}

		hasCollections = foundCollection;
		hasMutableProperties = foundMutable;

		iter = persistentClass.getSubclassIterator();
		while ( iter.hasNext() ) {
			subclassEntityNames.add( ( (PersistentClass) iter.next() ).getEntityName() );
		}
		subclassEntityNames.add( name );

		tuplizerMapping = new EntityEntityModeToTuplizerMapping( persistentClass, this );
	
Methods Summary
private org.hibernate.engine.ValueInclusiondetermineInsertValueGenerationType(org.hibernate.mapping.Property mappingProperty, org.hibernate.tuple.StandardProperty runtimeProperty)

		if ( runtimeProperty.isInsertGenerated() ) {
			return ValueInclusion.FULL;
		}
		else if ( mappingProperty.getValue() instanceof Component ) {
			if ( hasPartialInsertComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
				return ValueInclusion.PARTIAL;
			}
		}
		return ValueInclusion.NONE;
	
private org.hibernate.engine.ValueInclusiondetermineUpdateValueGenerationType(org.hibernate.mapping.Property mappingProperty, org.hibernate.tuple.StandardProperty runtimeProperty)

		if ( runtimeProperty.isUpdateGenerated() ) {
			return ValueInclusion.FULL;
		}
		else if ( mappingProperty.getValue() instanceof Component ) {
			if ( hasPartialUpdateComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
				return ValueInclusion.PARTIAL;
			}
		}
		return ValueInclusion.NONE;
	
public org.hibernate.engine.CascadeStyle[]getCascadeStyles()

		return cascadeStyles;
	
public org.hibernate.type.EntityTypegetEntityType()

		return entityType;
	
public org.hibernate.tuple.IdentifierPropertygetIdentifierProperty()

		return identifierProperty;
	
public java.lang.StringgetName()

		return name;
	
public int[]getNaturalIdentifierProperties()

		return naturalIdPropertyNumbers;
	
public boolean[]getNonlazyPropertyUpdateability()

		return nonlazyPropertyUpdateability;
	
public intgetOptimisticLockMode()

		return optimisticLockMode;
	
public org.hibernate.tuple.StandardProperty[]getProperties()

		return properties;
	
public boolean[]getPropertyCheckability()

		return propertyCheckability;
	
public intgetPropertyIndex(java.lang.String propertyName)

		Integer index = getPropertyIndexOrNull(propertyName);
		if ( index == null ) {
			throw new HibernateException("Unable to resolve property: " + propertyName);
		}
		return index.intValue();
	
public java.lang.IntegergetPropertyIndexOrNull(java.lang.String propertyName)

		return (Integer) propertyIndexes.get( propertyName );
	
public org.hibernate.engine.ValueInclusion[]getPropertyInsertGenerationInclusions()

		return insertInclusions;
	
public boolean[]getPropertyInsertability()

		return propertyInsertability;
	
public boolean[]getPropertyLaziness()

		return propertyLaziness;
	
public java.lang.String[]getPropertyNames()

		return propertyNames;
	
public boolean[]getPropertyNullability()

		return propertyNullability;
	
public intgetPropertySpan()

		return propertySpan;
	
public org.hibernate.type.Type[]getPropertyTypes()

		return propertyTypes;
	
public org.hibernate.engine.ValueInclusion[]getPropertyUpdateGenerationInclusions()

		return updateInclusions;
	
public boolean[]getPropertyUpdateability()

		return propertyUpdateability;
	
public boolean[]getPropertyVersionability()

		return propertyVersionability;
	
public java.lang.StringgetRootName()

		return rootName;
	
public org.hibernate.engine.SessionFactoryImplementorgetSessionFactory()

		return sessionFactory;
	
public java.util.SetgetSubclassEntityNames()

		return subclassEntityNames;
	
public java.lang.StringgetSuperclass()

		return superclass;
	
public EntityTuplizergetTuplizer(org.hibernate.EntityMode entityMode)


	    
		return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
	
public EntityTuplizergetTuplizerOrNull(org.hibernate.EntityMode entityMode)

		return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
	
public org.hibernate.tuple.VersionPropertygetVersionProperty()

		if ( NO_VERSION_INDX == versionPropertyIndex ) {
			return null;
		}
		else {
			return ( VersionProperty ) properties[ versionPropertyIndex ];
		}
	
public intgetVersionPropertyIndex()

		return versionPropertyIndex;
	
public org.hibernate.EntityModeguessEntityMode(java.lang.Object object)

		return tuplizerMapping.guessEntityMode( object );
	
public booleanhasCascades()

		return hasCascades;
	
public booleanhasCollections()

		return hasCollections;
	
public booleanhasInsertGeneratedValues()

		return hasInsertGeneratedValues;
	
public booleanhasLazyProperties()

		return hasLazyProperties;
	
public booleanhasMutableProperties()

		return hasMutableProperties;
	
public booleanhasNaturalIdentifier()

		return naturalIdPropertyNumbers!=null;
	
public booleanhasNonIdentifierPropertyNamedId()

		return hasNonIdentifierPropertyNamedId;
	
private booleanhasPartialInsertComponentGeneration(org.hibernate.mapping.Component component)

		Iterator subProperties = component.getPropertyIterator();
		while ( subProperties.hasNext() ) {
			Property prop = ( Property ) subProperties.next();
			if ( prop.getGeneration() == PropertyGeneration.ALWAYS || prop.getGeneration() == PropertyGeneration.INSERT ) {
				return true;
			}
			else if ( prop.getValue() instanceof Component ) {
				if ( hasPartialInsertComponentGeneration( ( Component ) prop.getValue() ) ) {
					return true;
				}
			}
		}
		return false;
	
private booleanhasPartialUpdateComponentGeneration(org.hibernate.mapping.Component component)

		Iterator subProperties = component.getPropertyIterator();
		while ( subProperties.hasNext() ) {
			Property prop = ( Property ) subProperties.next();
			if ( prop.getGeneration() == PropertyGeneration.ALWAYS ) {
				return true;
			}
			else if ( prop.getValue() instanceof Component ) {
				if ( hasPartialUpdateComponentGeneration( ( Component ) prop.getValue() ) ) {
					return true;
				}
			}
		}
		return false;
	
public booleanhasSubclasses()

		return hasSubclasses;
	
public booleanhasUpdateGeneratedValues()

		return hasUpdateGeneratedValues;
	
private booleanindicatesCollection(org.hibernate.type.Type type)

		if ( type.isCollectionType() ) {
			return true;
		}
		else if ( type.isComponentType() ) {
			Type[] subtypes = ( ( AbstractComponentType ) type ).getSubtypes();
			for ( int i = 0; i < subtypes.length; i++ ) {
				if ( indicatesCollection( subtypes[i] ) ) {
					return true;
				}
			}
		}
		return false;
	
public booleanisAbstract()

		return isAbstract;
	
public booleanisDynamicInsert()

		return dynamicInsert;
	
public booleanisDynamicUpdate()

		return dynamicUpdate;
	
public booleanisExplicitPolymorphism()

		return explicitPolymorphism;
	
public booleanisInherited()

		return inherited;
	
public booleanisLazy()

		return lazy;
	
public booleanisMutable()

		return mutable;
	
public booleanisPolymorphic()

		return polymorphic;
	
public booleanisSelectBeforeUpdate()

		return selectBeforeUpdate;
	
public booleanisVersioned()

		return versioned;
	
private voidmapPropertyToIndex(org.hibernate.mapping.Property prop, int i)

		propertyIndexes.put( prop.getName(), new Integer(i) );
		if ( prop.getValue() instanceof Component ) {
			Iterator iter = ( (Component) prop.getValue() ).getPropertyIterator();
			while ( iter.hasNext() ) {
				Property subprop = (Property) iter.next();
				propertyIndexes.put(
						prop.getName() + '." + subprop.getName(),
						new Integer(i)
					);
			}
		}
	
public voidsetLazy(boolean lazy)

		this.lazy = lazy;
	
public java.lang.StringtoString()

		return "EntityMetamodel(" + name + ':" + ArrayHelper.toString(properties) + ')";