Ejemplo n.º 1
0
		public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
		{
			this.sessionFactory = sessionFactory;


			name = persistentClass.EntityName;
			rootName = persistentClass.RootClazz.EntityName;
			entityType = TypeFactory.ManyToOne(name);
			type = persistentClass.MappedClass;
			rootType = persistentClass.RootClazz.MappedClass;
			rootTypeAssemblyQualifiedName = rootType.AssemblyQualifiedName;

			identifierProperty =
				PropertyFactory.BuildIdentifierProperty(persistentClass, sessionFactory.GetIdentifierGenerator(rootType));

			versioned = persistentClass.IsVersioned;

			bool lazyAvailable = persistentClass.HasPocoRepresentation && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
			bool hasLazy = false;

			propertySpan = persistentClass.PropertyClosureSpan;
			properties = new StandardProperty[propertySpan];
			List<int> naturalIdNumbers = new List<int>();

			#region temporary

			propertyNames = new string[propertySpan];
			propertyTypes = new IType[propertySpan];
			propertyUpdateability = new bool[propertySpan];
			propertyInsertability = new bool[propertySpan];
			insertInclusions = new ValueInclusion[propertySpan];
			updateInclusions = new ValueInclusion[propertySpan];
			nonlazyPropertyUpdateability = new bool[propertySpan];
			propertyCheckability = new bool[propertySpan];
			propertyNullability = new bool[propertySpan];
			propertyVersionability = new bool[propertySpan];
			propertyLaziness = new bool[propertySpan];
			cascadeStyles = new CascadeStyle[propertySpan];

			#endregion


			int i = 0;
			int tempVersionProperty = NoVersionIndex;
			bool foundCascade = false;
			bool foundCollection = false;
			bool foundMutable = false;
			bool foundInsertGeneratedValue = false;
			bool foundUpdateGeneratedValue = false;
			bool foundNonIdentifierPropertyNamedId = false;

			foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
			{
				if (prop == persistentClass.Version)
				{
					tempVersionProperty = i;
					properties[i] = PropertyFactory.BuildVersionProperty(prop, lazyAvailable);
				}
				else
				{
					properties[i] = PropertyFactory.BuildStandardProperty(prop, lazyAvailable);
				}

				if (prop.IsNaturalIdentifier)
				{
					naturalIdNumbers.Add(i);
				}

				if ("id".Equals(prop.Name))
				{
					foundNonIdentifierPropertyNamedId = true;
				}

				#region temporary
				bool lazyProperty = prop.IsLazy && lazyAvailable;
				if (lazyProperty)
					hasLazy = true;
				propertyLaziness[i] = lazyProperty;

				propertyNames[i] = properties[i].Name;
				propertyTypes[i] = properties[i].Type;
				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 && !lazyProperty;
				propertyCheckability[i] = propertyUpdateability[i] ||
				                          (propertyTypes[i].IsAssociationType &&
				                           ((IAssociationType) propertyTypes[i]).IsAlwaysDirtyChecked);

				cascadeStyles[i] = properties[i].CascadeStyle;
				#endregion

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

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

				if (IndicatesCollection(properties[i].Type))
				{
					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.Count == 0)
				naturalIdPropertyNumbers = null;
			else
				naturalIdPropertyNumbers = naturalIdNumbers.ToArray();

			hasCascades = foundCascade;
			hasInsertGeneratedValues = foundInsertGeneratedValue;
			hasUpdateGeneratedValues = foundUpdateGeneratedValue;
			hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

			versionPropertyIndex = tempVersionProperty;
			hasLazyProperties = hasLazy;
			if (hasLazyProperties) log.Info("lazy property fetching available for: " + name);

			lazy = persistentClass.IsLazy && 
				(!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
			mutable = persistentClass.IsMutable;

			if (!persistentClass.IsAbstract.HasValue)
			{
				// legacy behavior (with no abstract attribute specified)
				isAbstract = persistentClass.HasPocoRepresentation &&
				             ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
			}
			else
			{
				isAbstract = persistentClass.IsAbstract.Value;
				if (!isAbstract && persistentClass.HasPocoRepresentation &&
				    ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
				{
					log.Warn("entity [" + type.FullName +
					         "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
				}
			}
			selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
			dynamicUpdate = persistentClass.DynamicUpdate;
			dynamicInsert = persistentClass.DynamicInsert;

			polymorphic = persistentClass.IsPolymorphic;
			explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
			inherited = persistentClass.IsInherited;
			superclass = inherited ? persistentClass.Superclass.EntityName : null;
			superclassType = inherited ?
			                           	persistentClass.Superclass.MappedClass :
			                           	                                       	null;
			hasSubclasses = persistentClass.HasSubclasses;

			optimisticLockMode = persistentClass.OptimisticLockMode;
			if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
			{
				throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName);
			}

			hasCollections = foundCollection;
			hasMutableProperties = foundMutable;

			foreach (Subclass obj in persistentClass.SubclassIterator)
			{
				subclassEntityNames.Add(obj.EntityName);
			}
			subclassEntityNames.Add(name);

			tuplizerMapping = new EntityEntityModeToTuplizerMapping(persistentClass, this);
		}
Ejemplo n.º 2
0
		public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
		{
			this.sessionFactory = sessionFactory;


			name = persistentClass.EntityName;
			rootName = persistentClass.RootClazz.EntityName;
			entityType = TypeFactory.ManyToOne(name);
			type = persistentClass.MappedClass;
			rootType = persistentClass.RootClazz.MappedClass;
			rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName;

			identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass,
			                                                             sessionFactory.GetIdentifierGenerator(rootName));

			versioned = persistentClass.IsVersioned;

			bool lazyAvailable = persistentClass.HasPocoRepresentation
			                     && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
			bool hasLazy = false;

			propertySpan = persistentClass.PropertyClosureSpan;
			properties = new StandardProperty[propertySpan];
			List<int> naturalIdNumbers = new List<int>();

			propertyNames = new string[propertySpan];
			propertyTypes = new IType[propertySpan];
			propertyUpdateability = new bool[propertySpan];
			propertyInsertability = new bool[propertySpan];
			insertInclusions = new ValueInclusion[propertySpan];
			updateInclusions = new ValueInclusion[propertySpan];
			nonlazyPropertyUpdateability = new bool[propertySpan];
			propertyCheckability = new bool[propertySpan];
			propertyNullability = new bool[propertySpan];
			propertyVersionability = new bool[propertySpan];
			propertyLaziness = new bool[propertySpan];
			cascadeStyles = new CascadeStyle[propertySpan];

			int i = 0;
			int tempVersionProperty = NoVersionIndex;
			bool foundCascade = false;
			bool foundCollection = false;
			bool foundMutable = false;
			bool foundInsertGeneratedValue = false;
			bool foundUpdateGeneratedValue = false;
			bool foundNonIdentifierPropertyNamedId = false;
			HasPocoRepresentation = persistentClass.HasPocoRepresentation;
			
			// NH: WARNING if we have to disable lazy/unproxy properties we have to do it in the whole process.
			lazy = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
			lazyAvailable &= lazy; // <== Disable lazy properties if the class is marked with lazy=false

			bool hadLazyProperties = false;
			bool hadNoProxyRelations = false;
			foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
			{
				if (prop.IsLazy)
				{
					hadLazyProperties = true;
				}
				if(prop.UnwrapProxy)
				{
					hadNoProxyRelations = true;
				}

				// NH: A lazy property is a simple property marked with lazy=true
				bool islazyProperty = prop.IsLazy && lazyAvailable && (!prop.IsEntityRelation || prop.UnwrapProxy);
				// NH: A Relation (in this case many-to-one or one-to-one) marked as "no-proxy"
				var isUnwrapProxy = prop.UnwrapProxy && lazyAvailable;

				if (islazyProperty || isUnwrapProxy)
				{
					// NH: verify property proxiability
					var getter = prop.GetGetter(persistentClass.MappedClass);
					if (getter.Method == null || getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false)
					{
						log.ErrorFormat("Lazy or no-proxy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name);
					}
				}

				if (prop == persistentClass.Version)
				{
					tempVersionProperty = i;
					properties[i] = PropertyFactory.BuildVersionProperty(prop, islazyProperty);
				}
				else
				{
					properties[i] = PropertyFactory.BuildStandardProperty(prop, islazyProperty);
				}

				if (prop.IsNaturalIdentifier)
				{
					naturalIdNumbers.Add(i);
				}

				if ("id".Equals(prop.Name))
				{
					foundNonIdentifierPropertyNamedId = true;
				}

				if (islazyProperty)
				{
					hasLazy = true;
				}
				if (isUnwrapProxy)
				{
					hasUnwrapProxyForProperties = true;
				}

				propertyLaziness[i] = islazyProperty;

				propertyNames[i] = properties[i].Name;
				propertyTypes[i] = properties[i].Type;
				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 && !islazyProperty;
				propertyCheckability[i] = propertyUpdateability[i]
				                          ||
				                          (propertyTypes[i].IsAssociationType
				                           && ((IAssociationType) propertyTypes[i]).IsAlwaysDirtyChecked);

				cascadeStyles[i] = properties[i].CascadeStyle;

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

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

				if (IndicatesCollection(properties[i].Type))
				{
					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.Count == 0)
				naturalIdPropertyNumbers = null;
			else
				naturalIdPropertyNumbers = naturalIdNumbers.ToArray();

			hasCascades = foundCascade;
			hasInsertGeneratedValues = foundInsertGeneratedValue;
			hasUpdateGeneratedValues = foundUpdateGeneratedValue;
			hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

			versionPropertyIndex = tempVersionProperty;
			hasLazyProperties = hasLazy;

			if(hadLazyProperties && !hasLazy)
			{
				log.WarnFormat("Disabled lazy properies fetching for {0} beacuse it does not support lazy at the entity level", name);
			}
			if (hasLazy)
			{
				log.Info("lazy property fetching available for: " + name);
			}

			if(hadNoProxyRelations && !hasUnwrapProxyForProperties)
			{
				log.WarnFormat("Disabled ghost properies fetching for {0} beacuse it does not support lazy at the entity level", name);
			}
			if (hasUnwrapProxyForProperties)
			{
				log.Info("no-proxy property fetching available for: " + name);
			}

			mutable = persistentClass.IsMutable;

			if (!persistentClass.IsAbstract.HasValue)
			{
				// legacy behavior (with no abstract attribute specified)
				isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
			}
			else
			{
				isAbstract = persistentClass.IsAbstract.Value;
				if (!isAbstract && persistentClass.HasPocoRepresentation
				    && ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
				{
					log.Warn("entity [" + type.FullName
					         + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
				}
			}
			selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
			dynamicUpdate = persistentClass.DynamicUpdate;
			dynamicInsert = persistentClass.DynamicInsert;

			polymorphic = persistentClass.IsPolymorphic;
			explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
			inherited = persistentClass.IsInherited;
			superclass = inherited ? persistentClass.Superclass.EntityName : null;
			superclassType = inherited ? persistentClass.Superclass.MappedClass : null;
			hasSubclasses = persistentClass.HasSubclasses;

			optimisticLockMode = persistentClass.OptimisticLockMode;
			if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
			{
				throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName);
			}

			hasCollections = foundCollection;
			hasMutableProperties = foundMutable;

			foreach (Subclass obj in persistentClass.SubclassIterator)
			{
				subclassEntityNames.Add(obj.EntityName);
			}
			subclassEntityNames.Add(name);

			tuplizerMapping = new EntityEntityModeToTuplizerMapping(persistentClass, this);
		}
Ejemplo n.º 3
0
		public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
		{
			this.sessionFactory = sessionFactory;


			name = persistentClass.EntityName;
			rootName = persistentClass.RootClazz.EntityName;
			entityType = TypeFactory.ManyToOne(name);
			type = persistentClass.MappedClass;
			rootType = persistentClass.RootClazz.MappedClass;
			rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName;

			identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass,
			                                                             sessionFactory.GetIdentifierGenerator(rootName));

			versioned = persistentClass.IsVersioned;

			bool lazyAvailable = persistentClass.HasPocoRepresentation
			                     && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
			bool hasLazy = false;

			propertySpan = persistentClass.PropertyClosureSpan;
			properties = new StandardProperty[propertySpan];
			List<int> naturalIdNumbers = new List<int>();

			#region temporary

			propertyNames = new string[propertySpan];
			propertyTypes = new IType[propertySpan];
			propertyUpdateability = new bool[propertySpan];
			propertyInsertability = new bool[propertySpan];
			insertInclusions = new ValueInclusion[propertySpan];
			updateInclusions = new ValueInclusion[propertySpan];
			nonlazyPropertyUpdateability = new bool[propertySpan];
			propertyCheckability = new bool[propertySpan];
			propertyNullability = new bool[propertySpan];
			propertyVersionability = new bool[propertySpan];
			propertyLaziness = new bool[propertySpan];
			cascadeStyles = new CascadeStyle[propertySpan];

			#endregion


			int i = 0;
			int tempVersionProperty = NoVersionIndex;
			bool foundCascade = false;
			bool foundCollection = false;
			bool foundMutable = false;
			bool foundInsertGeneratedValue = false;
			bool foundUpdateGeneratedValue = false;
			bool foundNonIdentifierPropertyNamedId = false;

			foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
			{
				if (prop == persistentClass.Version)
				{
					tempVersionProperty = i;
					properties[i] = PropertyFactory.BuildVersionProperty(prop, lazyAvailable);
				}
				else
				{
					properties[i] = PropertyFactory.BuildStandardProperty(prop, lazyAvailable);
				}

				if (prop.IsNaturalIdentifier)
				{
					naturalIdNumbers.Add(i);
				}

				if ("id".Equals(prop.Name))
				{
					foundNonIdentifierPropertyNamedId = true;
				}

				#region temporary

				bool lazyProperty = prop.IsLazy && lazyAvailable;
				if (lazyProperty)
					hasLazy = true;
				propertyLaziness[i] = lazyProperty;

				propertyNames[i] = properties[i].Name;
				propertyTypes[i] = properties[i].Type;
				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 && !lazyProperty;
				propertyCheckability[i] = propertyUpdateability[i]
				                          ||
				                          (propertyTypes[i].IsAssociationType
				                           && ((IAssociationType) propertyTypes[i]).IsAlwaysDirtyChecked);

				cascadeStyles[i] = properties[i].CascadeStyle;

				#endregion

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

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

				if (IndicatesCollection(properties[i].Type))
				{
					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.Count == 0)
				naturalIdPropertyNumbers = null;
			else
				naturalIdPropertyNumbers = naturalIdNumbers.ToArray();

			hasCascades = foundCascade;
			hasInsertGeneratedValues = foundInsertGeneratedValue;
			hasUpdateGeneratedValues = foundUpdateGeneratedValue;
			hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

			versionPropertyIndex = tempVersionProperty;
			hasLazyProperties = hasLazy;
			if (hasLazyProperties) log.Info("lazy property fetching available for: " + name);

			lazy = persistentClass.IsLazy
			       && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
			mutable = persistentClass.IsMutable;

			if (!persistentClass.IsAbstract.HasValue)
			{
				// legacy behavior (with no abstract attribute specified)
				isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
			}
			else
			{
				isAbstract = persistentClass.IsAbstract.Value;
				if (!isAbstract && persistentClass.HasPocoRepresentation
				    && ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
				{
					log.Warn("entity [" + type.FullName
					         + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
				}
			}
			selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
			dynamicUpdate = persistentClass.DynamicUpdate;
			dynamicInsert = persistentClass.DynamicInsert;

			polymorphic = persistentClass.IsPolymorphic;
			explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
			inherited = persistentClass.IsInherited;
			superclass = inherited ? persistentClass.Superclass.EntityName : null;
			superclassType = inherited ? persistentClass.Superclass.MappedClass : null;
			hasSubclasses = persistentClass.HasSubclasses;

			optimisticLockMode = persistentClass.OptimisticLockMode;
			if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
			{
				throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName);
			}

			hasCollections = foundCollection;
			hasMutableProperties = foundMutable;

			foreach (Subclass obj in persistentClass.SubclassIterator)
			{
				subclassEntityNames.Add(obj.EntityName);
			}
			subclassEntityNames.Add(name);

			tuplizerMapping = new EntityEntityModeToTuplizerMapping(persistentClass, this);
		}
Ejemplo n.º 4
0
        public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
        {
            this.sessionFactory = sessionFactory;


            name       = persistentClass.EntityName;
            rootName   = persistentClass.RootClazz.EntityName;
            entityType = TypeFactory.ManyToOne(name);
            type       = persistentClass.MappedClass;
            rootType   = persistentClass.RootClazz.MappedClass;
            rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName;

            identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass,
                                                                         sessionFactory.GetIdentifierGenerator(rootName));

            versioned = persistentClass.IsVersioned;

            bool lazyAvailable = persistentClass.HasPocoRepresentation &&
                                 FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
            bool hasLazy = false;

            propertySpan = persistentClass.PropertyClosureSpan;
            properties   = new StandardProperty[propertySpan];
            List <int> naturalIdNumbers = new List <int>();

            propertyNames                = new string[propertySpan];
            propertyTypes                = new IType[propertySpan];
            propertyUpdateability        = new bool[propertySpan];
            propertyInsertability        = new bool[propertySpan];
            insertInclusions             = new ValueInclusion[propertySpan];
            updateInclusions             = new ValueInclusion[propertySpan];
            nonlazyPropertyUpdateability = new bool[propertySpan];
            propertyCheckability         = new bool[propertySpan];
            propertyNullability          = new bool[propertySpan];
            propertyVersionability       = new bool[propertySpan];
            propertyLaziness             = new bool[propertySpan];
            cascadeStyles                = new CascadeStyle[propertySpan];

            int  i = 0;
            int  tempVersionProperty               = NoVersionIndex;
            bool foundCascade                      = false;
            bool foundCollection                   = false;
            bool foundMutable                      = false;
            bool foundInsertGeneratedValue         = false;
            bool foundUpdateGeneratedValue         = false;
            bool foundNonIdentifierPropertyNamedId = false;

            HasPocoRepresentation = persistentClass.HasPocoRepresentation;

            // NH: WARNING if we have to disable lazy/unproxy properties we have to do it in the whole process.
            lazy           = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
            lazyAvailable &= lazy;             // <== Disable lazy properties if the class is marked with lazy=false

            bool hadLazyProperties   = false;
            bool hadNoProxyRelations = false;

            foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
            {
                if (prop.IsLazy)
                {
                    hadLazyProperties = true;
                }
                if (prop.UnwrapProxy)
                {
                    hadNoProxyRelations = true;
                }

                // NH: A lazy property is a simple property marked with lazy=true
                bool islazyProperty = prop.IsLazy && lazyAvailable && (!prop.IsEntityRelation || prop.UnwrapProxy);
                // NH: A Relation (in this case many-to-one or one-to-one) marked as "no-proxy"
                var isUnwrapProxy = prop.UnwrapProxy && lazyAvailable;

                if (islazyProperty || isUnwrapProxy)
                {
                    // NH: verify property proxiability
                    var getter = prop.GetGetter(persistentClass.MappedClass);
                    if (getter.Method == null || getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false)
                    {
                        log.ErrorFormat("Lazy or no-proxy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name);
                    }
                }

                if (prop == persistentClass.Version)
                {
                    tempVersionProperty = i;
                    properties[i]       = PropertyFactory.BuildVersionProperty(prop, islazyProperty);
                }
                else
                {
                    properties[i] = PropertyFactory.BuildStandardProperty(prop, islazyProperty);
                }

                if (prop.IsNaturalIdentifier)
                {
                    naturalIdNumbers.Add(i);
                }

                if ("id".Equals(prop.Name))
                {
                    foundNonIdentifierPropertyNamedId = true;
                }

                if (islazyProperty)
                {
                    hasLazy = true;
                }
                if (isUnwrapProxy)
                {
                    hasUnwrapProxyForProperties = true;
                }

                propertyLaziness[i] = islazyProperty;

                propertyNames[i]                = properties[i].Name;
                propertyTypes[i]                = properties[i].Type;
                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 && !islazyProperty;
                propertyCheckability[i]         = propertyUpdateability[i]
                                                  ||
                                                  (propertyTypes[i].IsAssociationType &&
                                                   ((IAssociationType)propertyTypes[i]).IsAlwaysDirtyChecked);

                cascadeStyles[i] = properties[i].CascadeStyle;

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

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

                if (IndicatesCollection(properties[i].Type))
                {
                    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.Count == 0)
            {
                naturalIdPropertyNumbers = null;
            }
            else
            {
                naturalIdPropertyNumbers = naturalIdNumbers.ToArray();
            }

            hasCascades = foundCascade;
            hasInsertGeneratedValues        = foundInsertGeneratedValue;
            hasUpdateGeneratedValues        = foundUpdateGeneratedValue;
            hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

            versionPropertyIndex = tempVersionProperty;
            hasLazyProperties    = hasLazy;

            if (hadLazyProperties && !hasLazy)
            {
                log.WarnFormat("Disabled lazy property fetching for {0} because it does not support lazy at the entity level", name);
            }
            if (hasLazy)
            {
                log.Info("lazy property fetching available for: " + name);
            }

            if (hadNoProxyRelations && !hasUnwrapProxyForProperties)
            {
                log.WarnFormat("Disabled ghost property fetching for {0} because it does not support lazy at the entity level", name);
            }
            if (hasUnwrapProxyForProperties)
            {
                log.Info("no-proxy property fetching available for: " + name);
            }

            mutable = persistentClass.IsMutable;

            if (!persistentClass.IsAbstract.HasValue)
            {
                // legacy behavior (with no abstract attribute specified)
                isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
            }
            else
            {
                isAbstract = persistentClass.IsAbstract.Value;
                if (!isAbstract && persistentClass.HasPocoRepresentation &&
                    ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
                {
                    log.Warn("entity [" + type.FullName
                             + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
                }
            }
            selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
            dynamicUpdate      = persistentClass.DynamicUpdate;
            dynamicInsert      = persistentClass.DynamicInsert;

            polymorphic          = persistentClass.IsPolymorphic;
            explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
            inherited            = persistentClass.IsInherited;
            superclass           = inherited ? persistentClass.Superclass.EntityName : null;
            superclassType       = inherited ? persistentClass.Superclass.MappedClass : null;
            hasSubclasses        = persistentClass.HasSubclasses;

            optimisticLockMode = persistentClass.OptimisticLockMode;
            if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
            {
                throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName);
            }

            hasCollections       = foundCollection;
            hasMutableProperties = foundMutable;

            foreach (Subclass obj in persistentClass.SubclassIterator)
            {
                subclassEntityNames.Add(obj.EntityName);
            }
            subclassEntityNames.Add(name);

            EntityMode = persistentClass.HasPocoRepresentation ? EntityMode.Poco : EntityMode.Map;

            var entityTuplizerFactory = new EntityTuplizerFactory();
            var tuplizerClassName     = persistentClass.GetTuplizerImplClassName(EntityMode);

            Tuplizer = tuplizerClassName == null
                                ? entityTuplizerFactory.BuildDefaultEntityTuplizer(EntityMode, this, persistentClass)
                                : entityTuplizerFactory.BuildEntityTuplizer(tuplizerClassName, this, persistentClass);
        }