/// <summary> /// Constructs VersionProperty instances. /// </summary> /// <param name="name">The name by which the property can be referenced within /// its owner.</param> /// <param name="node">The node name to use for XML-based representation of this /// property.</param> /// <param name="type">The Hibernate Type of this property.</param> /// <param name="lazy">Should this property be handled lazily?</param> /// <param name="insertable">Is this property an insertable value?</param> /// <param name="updateable">Is this property an updateable value?</param> /// <param name="insertGenerated">Is this property generated in the database on insert?</param> /// <param name="updateGenerated">Is this property generated in the database on update?</param> /// <param name="nullable">Is this property a nullable value?</param> /// <param name="checkable">Is this property a checkable value?</param> /// <param name="versionable">Is this property a versionable value?</param> /// <param name="cascadeStyle">The cascade style for this property's value.</param> /// <param name="unsavedValue">The value which, if found as the value of /// this (i.e., the version) property, represents new (i.e., un-saved) /// instances of the owning entity.</param> public VersionProperty( string name, string node, IType type, bool lazy, bool insertable, bool updateable, bool insertGenerated, bool updateGenerated, bool nullable, bool checkable, bool versionable, Cascades.CascadeStyle cascadeStyle, Cascades.VersionValue unsavedValue) : base( name, node, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable, cascadeStyle) { this.unsavedValue = unsavedValue; }
protected AbstractEntityPersister( PersistentClass model, ISessionFactoryImplementor factory ) { dialect = factory.Dialect; //sqlExceptionConverter = factory.SQLExceptionConverter; // CLASS className = model.MappedClass.FullName; rootClassName = model.RootClazz.Name; mappedClass = model.MappedClass; mutable = model.IsMutable; selectBeforeUpdate = model.SelectBeforeUpdate; dynamicUpdate = model.DynamicUpdate; dynamicInsert = model.DynamicInsert; sqlWhereString = model.Where; sqlWhereStringTemplate = sqlWhereString == null ? null : Template.RenderWhereStringTemplate( sqlWhereString, Dialect ); polymorphic = model.IsPolymorphic; explicitPolymorphism = model.IsExplicitPolymorphism; inherited = model.IsInherited; superclass = inherited ? model.Superclass.MappedClass : null; hasSubclasses = model.HasSubclasses; batchSize = model.BatchSize; constructor = ReflectHelper.GetDefaultConstructor( mappedClass ); abstractClass = ReflectHelper.IsAbstractClass( mappedClass ); entityType = NHibernateUtil.Entity( mappedClass ); optimisticLockMode = model.OptimisticLockMode; if( optimisticLockMode > OptimisticLockMode.Version && !dynamicUpdate ) { throw new MappingException( string.Format( "optimistic-lock setting requires dynamic-update=\'true\': {0}", className ) ); } // verify that the class has a default constructor if it is not abstract - it is considered // a mapping exception if the default ctor is missing. if( abstractClass == false && constructor == null ) { throw new MappingException( "The mapped class " + mappedClass.FullName + " must declare a default (no-arg) constructor." ); } // IDENTIFIER hasEmbeddedIdentifier = model.HasEmbeddedIdentifier; IValue idValue = model.Identifier; identifierType = idValue.Type; if( model.HasIdentifierProperty ) { Mapping.Property idProperty = model.IdentifierProperty; identifierPropertyName = idProperty.Name; identifierSetter = idProperty.GetSetter( mappedClass ); identifierGetter = idProperty.GetGetter( mappedClass ); } else { identifierPropertyName = null; identifierGetter = null; identifierSetter = null; } System.Type prox = model.ProxyInterface; MethodInfo proxySetIdentifierMethod = null; MethodInfo proxyGetIdentifierMethod = null; if( model.HasIdentifierProperty && prox != null ) { Mapping.Property idProperty = model.IdentifierProperty; PropertyInfo getIdPropertyInfo = idProperty.GetGetter( prox ).Property; if( getIdPropertyInfo != null ) { proxyGetIdentifierMethod = getIdPropertyInfo.GetGetMethod( true ); } PropertyInfo setIdPropertyInfo = idProperty.GetSetter( prox ).Property; if( setIdPropertyInfo != null ) { proxySetIdentifierMethod = setIdPropertyInfo.GetSetMethod( true ); } } // HYDRATE SPAN hydrateSpan = model.PropertyClosureCollection.Count; // IDENTIFIER int idColumnSpan = model.Identifier.ColumnSpan; identifierColumnNames = new string[idColumnSpan]; identifierAliases = new string[idColumnSpan]; int i = 0; foreach( Column col in idValue.ColumnCollection ) { identifierColumnNames[ i ] = col.GetQuotedName( Dialect ); identifierAliases[ i ] = col.Alias( Dialect ); i++; } // GENERATOR identifierGenerator = model.Identifier.CreateIdentifierGenerator( Dialect ); useIdentityColumn = identifierGenerator is IdentityGenerator; identitySelectString = useIdentityColumn ? dialect.IdentitySelectString : null; // UNSAVED-VALUE: unsavedIdentifierValue = UnsavedValueFactory.GetUnsavedIdentifierValue( model.Identifier.NullValue, identifierGetter, identifierType, constructor ); // VERSION: if( model.IsVersioned ) { foreach( Column col in model.Version.ColumnCollection ) { versionColumnName = col.GetQuotedName( Dialect ); break; //only happens once } } else { versionColumnName = null; } if( model.IsVersioned ) { //versionPropertyName = model.Version.Name; versioned = true; versionGetter = model.Version.GetGetter( mappedClass ); versionType = ( IVersionType ) model.Version.Type; } else { //versionPropertyName = null; versioned = false; versionGetter = null; versionType = null; } // VERSION UNSAVED-VALUE: unsavedVersionValue = model.IsVersioned ? UnsavedValueFactory.GetUnsavedVersionValue( model.Version.NullValue, versionGetter, versionType, constructor ) : Cascades.VersionValue.VersionUndefined; // PROPERTIES propertyTypes = new IType[hydrateSpan]; propertyNames = new string[hydrateSpan]; propertyUpdateability = new bool[hydrateSpan]; propertyInsertability = new bool[hydrateSpan]; propertyNullability = new bool[hydrateSpan]; getters = new IGetter[hydrateSpan]; setters = new ISetter[hydrateSpan]; cascadeStyles = new Cascades.CascadeStyle[hydrateSpan]; string[ ] setterNames = new string[hydrateSpan]; string[ ] getterNames = new string[hydrateSpan]; System.Type[ ] types = new System.Type[hydrateSpan]; i = 0; int tempVersionProperty = -66; bool foundCascade = false; bool foundCustomAccessor = false; foreach( Mapping.Property prop in model.PropertyClosureCollection ) { if( prop == model.Version ) { tempVersionProperty = i; } propertyNames[ i ] = prop.Name; if( !prop.IsBasicPropertyAccessor ) { foundCustomAccessor = true; } getters[ i ] = prop.GetGetter( mappedClass ); setters[ i ] = prop.GetSetter( mappedClass ); getterNames[ i ] = getters[ i ].PropertyName; setterNames[ i ] = setters[ i ].PropertyName; types[ i ] = getters[ i ].ReturnType; propertyTypes[ i ] = prop.Type; propertyUpdateability[ i ] = prop.IsUpdateable; propertyInsertability[ i ] = prop.IsInsertable; propertyNullability[ i ] = prop.IsNullable; gettersByPropertyName[ propertyNames[ i ] ] = getters[ i ]; settersByPropertyName[ propertyNames[ i ] ] = setters[ i ]; typesByPropertyName[ propertyNames[ i ] ] = propertyTypes[ i ]; cascadeStyles[ i ] = prop.CascadeStyle; if( cascadeStyles[ i ] != Cascades.CascadeStyle.StyleNone ) { foundCascade = true; } i++; } // NH: reflection optimizer works with custom accessors if( /*!foundCustomAccessor &&*/ Cfg.Environment.UseReflectionOptimizer ) { getset = GetSetHelperFactory.Create( MappedClass, Setters, Getters ); } hasCascades = foundCascade; versionProperty = tempVersionProperty; // CALLBACK INTERFACES implementsLifecycle = typeof( ILifecycle ).IsAssignableFrom( mappedClass ); implementsValidatable = typeof( IValidatable ).IsAssignableFrom( mappedClass ); cache = model.Cache; hasCollections = InitHasCollections(); // PROXIES concreteProxyClass = model.ProxyInterface; hasProxy = concreteProxyClass != null; if( hasProxy ) { HashedSet proxyInterfaces = new HashedSet(); proxyInterfaces.Add( typeof( INHibernateProxy ) ); if( !mappedClass.Equals( concreteProxyClass ) ) { if( !concreteProxyClass.IsInterface ) { throw new MappingException( "proxy must be either an interface, or the class itself: " + mappedClass.FullName ); } proxyInterfaces.Add( concreteProxyClass ); } if( mappedClass.IsInterface ) { proxyInterfaces.Add( mappedClass ); } if( hasProxy ) { foreach( Subclass subclass in model.SubclassCollection ) { System.Type subclassProxy = subclass.ProxyInterface; if( subclassProxy == null ) { throw new MappingException( "All subclasses must also have proxies: " + mappedClass.Name ); } if( !subclass.MappedClass.Equals( subclassProxy ) ) { proxyInterfaces.Add( subclassProxy ); } } } if( hasProxy ) { proxyFactory = CreateProxyFactory(); proxyFactory.PostInstantiate( mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod ); } else { proxyFactory = null; } } else { proxyFactory = null; } }