예제 #1
0
 protected override JoinType GetJoinType(
     IAssociationType type,
     OuterJoinFetchStrategy config,
     string path,
     string table,
     string[] foreignKeyColumns,
     ISessionFactoryImplementor factory)
 {
     if (criteria.IsJoin(path))
     {
         return(JoinType.InnerJoin);
     }
     else
     {
         FetchMode fm = criteria.GetFetchMode(path);
         //fm==null ||  - an Enum can't be null
         if (fm == FetchMode.Default)
         {
             return(base.GetJoinType(type, config, path, table, foreignKeyColumns, factory));
         }
         else
         {
             return(fm == FetchMode.Eager ? JoinType.LeftOuterJoin : JoinType.None);
         }
     }
 }
		protected virtual JoinType GetJoinType( IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory )
		{
			bool mappingDefault = IsJoinedFetchEnabledByDefault( config, type, factory );
			return IsJoinedFetchEnabled( type, mappingDefault, path, table, foreignKeyColumns) ?
				JoinType.LeftOuterJoin :
				JoinType.None;
		}
예제 #3
0
        protected virtual JoinType GetJoinType(IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory)
        {
            bool mappingDefault = IsJoinedFetchEnabledByDefault(config, type, factory);

            return(IsJoinedFetchEnabled(type, mappingDefault, path, table, foreignKeyColumns) ?
                   JoinType.LeftOuterJoin :
                   JoinType.None);
        }
		public DynamicComponentType(
			string[ ] propertyNames,
			IType[ ] propertyTypes,
			OuterJoinFetchStrategy[ ] joinedFetch,
			Cascades.CascadeStyle[ ] cascade
			)
		{
			this.propertyNames = propertyNames;
			this.propertyTypes = propertyTypes;
			this.joinedFetch = joinedFetch;
			this.cascade = cascade;
			propertySpan = propertyTypes.Length;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="componentClass"></param>
		/// <param name="propertyNames"></param>
		/// <param name="propertyGetters"></param>
		/// <param name="propertySetters"></param>
		/// <param name="foundCustomAcessor"></param>
		/// <param name="propertyTypes"></param>
		/// <param name="joinedFetch"></param>
		/// <param name="cascade"></param>
		/// <param name="parentProperty"></param>
		public ComponentType( System.Type componentClass,
		                      string[ ] propertyNames,
		                      IGetter[ ] propertyGetters,
		                      ISetter[ ] propertySetters,
		                      // currently not used, see the comment near the end of the method body
							  bool foundCustomAcessor,
		                      IType[ ] propertyTypes,
		                      OuterJoinFetchStrategy[ ] joinedFetch,
		                      Cascades.CascadeStyle[ ] cascade,
		                      string parentProperty)
		{
			this.componentClass = componentClass;
			this.propertyTypes = propertyTypes;
			propertySpan = propertyNames.Length;
			getters = propertyGetters;
			setters = propertySetters;
			string[ ] getterNames = new string[propertySpan];
			string[ ] setterNames = new string[propertySpan];
			System.Type[ ] propTypes = new System.Type[propertySpan];
			for( int i = 0; i < propertySpan; i++ )
			{
				getterNames[ i ] = getters[ i ].PropertyName;
				setterNames[ i ] = setters[ i ].PropertyName;
				propTypes[ i ] = getters[ i ].ReturnType;
			}

			if( parentProperty == null )
			{
				parentSetter = null;
				parentGetter = null;
			}
			else
			{
				IPropertyAccessor pa = PropertyAccessorFactory.GetPropertyAccessor( null );
				parentSetter = pa.GetSetter( componentClass, parentProperty );
				parentGetter = pa.GetGetter( componentClass, parentProperty );
			}
			this.propertyNames = propertyNames;
			this.cascade = cascade;
			this.joinedFetch = joinedFetch;

			// NH: reflection optimizer works with custom accessors
			if( /*!foundCustomAcessor &&*/ Cfg.Environment.UseReflectionOptimizer )
			{
				this.getset = GetSetHelperFactory.Create(componentClass, setters, getters);
			}
		}
예제 #6
0
        protected override JoinType GetJoinType(
            IAssociationType type,
            OuterJoinFetchStrategy config,
            string path,
            string table,
            string[] foreignKeyColumns,
            ISessionFactoryImplementor factory
            )
        {
            JoinType joinType = base.GetJoinType(type, config, path, table, foreignKeyColumns, factory);

            // We can use an inner-join for the many-to-many
            if (joinType == JoinType.LeftOuterJoin && string.Empty.Equals(path))
            {
                joinType = JoinType.InnerJoin;
            }
            return(joinType);
        }
예제 #7
0
        /// <summary>
        /// Does the mapping, and Hibernate default semantics, specify that
        /// this association should be fetched by outer joining
        /// </summary>
        /// <param name="config"></param>
        /// <param name="type"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        protected bool IsJoinedFetchEnabledByDefault(OuterJoinFetchStrategy config, IAssociationType type, ISessionFactoryImplementor factory)
        {
            if (!type.IsEntityType && !type.IsPersistentCollectionType)
            {
                return(false);
            }
            else
            {
                switch (config)
                {
                case OuterJoinFetchStrategy.Eager:
                    return(true);

                case OuterJoinFetchStrategy.Lazy:
                    return(false);

                case OuterJoinFetchStrategy.Auto:
                    if (!factory.IsOuterJoinedFetchEnabled)
                    {
                        return(false);
                    }
                    if (type.IsEntityType)
                    {
                        EntityType      entityType = type as EntityType;
                        IClassPersister persister  = factory.GetPersister(entityType.AssociatedClass);
                        return(!persister.HasProxy || (
                                   entityType.IsOneToOne &&
                                   ((OneToOneType)entityType).IsNullable
                                   ));
                    }
                    else
                    {
                        return(false);
                    }

                default:
                    throw new ArgumentOutOfRangeException("config", config, "Unknown OJ strategy " + config.ToString());
                }
            }
        }
예제 #8
0
		public static void BindComponent( XmlNode node, Component model, System.Type reflectedClass, string className, string path, bool isNullable, Mappings mappings )
		{
			XmlAttribute classNode = node.Attributes[ "class" ];

			if( "dynamic-component".Equals( node.Name ) )
			{
				model.IsEmbedded = false;
				model.IsDynamic = true;
			}
			else if( classNode != null )
			{
				model.ComponentClass = ClassForNameChecked(
					classNode.Value, mappings,
					"component class not found: {0}" );
				model.IsEmbedded = false;
			}
			else if( reflectedClass != null )
			{
				model.ComponentClass = reflectedClass;
				model.IsEmbedded = false;
			}
			else
			{
				// an "embedded" component (ids only)
				model.ComponentClass = model.Owner.MappedClass;
				model.IsEmbedded = true;
			}

			foreach( XmlNode subnode in node.ChildNodes )
			{
				//I am only concerned with elements that are from the nhibernate namespace
				if( subnode.NamespaceURI != Configuration.MappingSchemaXMLNS )
				{
					continue;
				}

				string name = subnode.LocalName; //.Name;
				string propertyName = GetPropertyName( subnode );
				string subpath = propertyName == null ? null : StringHelper.Qualify( path, propertyName );

				CollectionType collectType = CollectionType.CollectionTypeFromString( name );
				IValue value = null;
				if( collectType != null )
				{
					Mapping.Collection collection = collectType.Create( subnode, className, subpath, model.Owner, mappings );
					mappings.AddCollection( collection );
					value = collection;
				}
				else if( "many-to-one".Equals( name ) || "key-many-to-one".Equals( name ) )
				{
					value = new ManyToOne( model.Table );
					BindManyToOne( subnode, ( ManyToOne ) value, subpath, isNullable, mappings );
				}
				else if( "one-to-one".Equals( name ) )
				{
					value = new OneToOne( model.Table, model.Owner.Identifier );
					BindOneToOne( subnode, ( OneToOne ) value, isNullable, mappings );
				}
				else if( "any".Equals( name ) )
				{
					value = new Any( model.Table );
					BindAny( subnode, ( Any ) value, isNullable, mappings );
				}
				else if( "property".Equals( name ) || "key-property".Equals( name ) )
				{
					value = new SimpleValue( model.Table );
					BindSimpleValue( subnode, ( SimpleValue ) value, isNullable, subpath, mappings );
				}
				else if( "component".Equals( name ) || "dynamic-component".Equals( name ) || "nested-composite-element".Equals( name ) )
				{
					System.Type subreflectedClass = model.ComponentClass == null ?
						null :
						GetPropertyType( subnode, mappings, model.ComponentClass, propertyName );
					value = ( model.Owner != null ) ?
						new Component( model.Owner ) : // a class component
						new Component( model.Table ); // a composite element
					BindComponent( subnode, ( Component ) value, subreflectedClass, className, subpath, isNullable, mappings );
				}
				else if( "parent".Equals( name ) )
				{
					model.ParentProperty = propertyName;
				}

				if( value != null )
				{
					model.AddProperty( CreateProperty( value, propertyName, model.ComponentClass, subnode, mappings ) );
				}
			}

			int span = model.PropertySpan;
			string[ ] names = new string[span];
			IType[ ] types = new IType[span];
			Cascades.CascadeStyle[ ] cascade = new Cascades.CascadeStyle[span];
			OuterJoinFetchStrategy[ ] joinedFetch = new OuterJoinFetchStrategy[span];

			int i = 0;
			foreach( Mapping.Property prop in model.PropertyCollection )
			{
				if( prop.IsFormula )
				{
					throw new MappingException( "properties of components may not be formulas: " + prop.Name );
				}
				if( !prop.IsInsertable || !prop.IsUpdateable )
				{
					throw new MappingException( "insert=\"false\", update=\"false\" not supported for properties of components: " + prop.Name );
				}
				names[ i ] = prop.Name;
				types[ i ] = prop.Type;
				cascade[ i ] = prop.CascadeStyle;
				joinedFetch[ i ] = prop.Value.OuterJoinFetchSetting;
				i++;
			}

			IType componentType;
			if( model.IsDynamic )
			{
				componentType = new DynamicComponentType( names, types, joinedFetch, cascade );
			}
			else
			{
				IGetter[ ] getters = new IGetter[span];
				ISetter[ ] setters = new ISetter[span];
				bool foundCustomAccessor = false;
				i = 0;
				foreach( Mapping.Property prop in model.PropertyCollection )
				{
					setters[ i ] = prop.GetSetter( model.ComponentClass );
					getters[ i ] = prop.GetGetter( model.ComponentClass );
					if( !prop.IsBasicPropertyAccessor )
					{
						foundCustomAccessor = true;
					}
					i++;
				}

				componentType = new ComponentType(
					model.ComponentClass,
					names,
					getters,
					setters,
					foundCustomAccessor,
					types,
					joinedFetch,
					cascade,
					model.ParentProperty );
			}
			model.Type = componentType;
		}
		public AbstractCollectionPersister( Mapping.Collection collection, ISessionFactoryImplementor factory )
		{
			this.factory = factory;
			dialect = factory.Dialect;
			//sqlExceptionConverter = factory.SQLExceptionConverter;
			collectionType = collection.CollectionType;
			role = collection.Role;
			ownerClass = collection.OwnerClass;
			Alias alias = new Alias( "__" );

			sqlOrderByString = collection.OrderBy;
			hasOrder = sqlOrderByString != null;
			sqlOrderByStringTemplate = hasOrder ? Template.RenderOrderByStringTemplate( sqlOrderByString, dialect ) : null;

			sqlWhereString = collection.Where;
			hasWhere = sqlWhereString != null;
			sqlWhereStringTemplate = hasWhere ? Template.RenderWhereStringTemplate( sqlWhereString, dialect ) : null;

			hasOrphanDelete = collection.OrphanDelete;

			batchSize = collection.BatchSize;

			cache = collection.Cache;

			keyType = collection.Key.Type;
			int keySpan = collection.Key.ColumnSpan;
			keyColumnNames = new string[keySpan];
			string[ ] keyAliases = new string[keySpan];
			int k = 0;
			foreach( Column col in collection.Key.ColumnCollection )
			{
				keyColumnNames[ k ] = col.GetQuotedName( dialect );
				keyAliases[ k ] = col.Alias( dialect );
				k++;
			}
			keyColumnAliases = alias.ToAliasStrings( keyAliases, dialect );
			//unquotedKeyColumnNames = StringHelper.Unquote( keyColumnAliases );
			ISet distinctColumns = new HashedSet();
			CheckColumnDuplication( distinctColumns, collection.Key.ColumnCollection );

			//isSet = collection.IsSet;
			//isSorted = collection.IsSorted;
			primitiveArray = collection.IsPrimitiveArray;
			array = collection.IsArray;

			IValue element = collection.Element;
			int elementSpan = element.ColumnSpan;
			ICollection iter = element.ColumnCollection;
			Table table = collection.CollectionTable;
			enableJoinedFetch = element.OuterJoinFetchSetting;
			elementType = element.Type;

			if( !collection.IsOneToMany )
			{
				CheckColumnDuplication( distinctColumns, element.ColumnCollection );
			}

			if( elementType.IsEntityType )
			{
				elementPersister = factory.GetPersister( ( ( EntityType ) elementType ).AssociatedClass );
			}
			else
			{
				elementPersister = null;
			}

			qualifiedTableName = table.GetQualifiedName( dialect, factory.DefaultSchema );
			string[ ] aliases = new string[elementSpan];
			elementColumnNames = new string[elementSpan];
			int j = 0;
			foreach( Column col in iter )
			{
				elementColumnNames[ j ] = col.GetQuotedName( dialect );
				aliases[ j ] = col.Alias( dialect );
				j++;
			}

			elementColumnAliases = alias.ToAliasStrings( aliases, dialect );

			IType selectColumns;
			string[ ] selectType;

			hasIndex = collection.IsIndexed;

			if( hasIndex )
			{
				IndexedCollection indexedCollection = ( IndexedCollection ) collection;

				indexType = indexedCollection.Index.Type;
				int indexSpan = indexedCollection.Index.ColumnSpan;
				indexColumnNames = new string[indexSpan];

				string[ ] indexAliases = new string[indexSpan];
				int i = 0;
				foreach( Column indexCol in indexedCollection.Index.ColumnCollection )
				{
					indexAliases[ i ] = indexCol.Alias( dialect );
					indexColumnNames[ i ] = indexCol.GetQuotedName( dialect );
					i++;
				}
				selectType = indexColumnNames;
				selectColumns = indexType;
				indexColumnAliases = alias.ToAliasStrings( indexAliases, dialect );
				CheckColumnDuplication( distinctColumns, indexedCollection.Index.ColumnCollection );
			}
			else
			{
				indexType = null;
				indexColumnNames = null;
				indexColumnAliases = null;
				selectType = elementColumnNames;
				selectColumns = elementType;
			}

			hasIdentifier = collection.IsIdentified;

			if( hasIdentifier )
			{
				if( collection.IsOneToMany )
				{
					throw new MappingException( "one-to-many collections with identifiers are not supported." );
				}
				IdentifierCollection idColl = ( IdentifierCollection ) collection;
				identifierType = idColl.Identifier.Type;

				Column col = null;
				foreach( Column column in idColl.Identifier.ColumnCollection )
				{
					col = column;
					break;
				}

				identifierColumnName = col.GetQuotedName( dialect );
				selectType = new string[ ] {identifierColumnName};
				selectColumns = identifierType;
				identifierColumnAlias = alias.ToAliasString( col.Alias( dialect ), dialect );
				unquotedIdentifierColumnName = identifierColumnAlias;
				identifierGenerator = idColl.Identifier.CreateIdentifierGenerator( dialect );
				CheckColumnDuplication( distinctColumns, idColl.Identifier.ColumnCollection );
			}
			else
			{
				identifierType = null;
				identifierColumnName = null;
				identifierColumnAlias = null;
				unquotedIdentifierColumnName = null;
				identifierGenerator = null;
			}

			rowSelectColumnNames = selectType;
			rowSelectType = selectColumns;

			sqlDeleteString = GenerateDeleteString();
			sqlInsertRowString = GenerateInsertRowString();
			sqlUpdateRowString = GenerateUpdateRowString();
			sqlDeleteRowString = GenerateDeleteRowString();
			isLazy = collection.IsLazy;

			isInverse = collection.IsInverse;

			if( collection.IsArray )
			{
				elementClass = ( ( Array ) collection ).ElementClass;
			}
			else
			{
				// for non-arrays, we don't need to know the element class
				elementClass = null;
			}

			initializer = CreateCollectionInitializer( factory );

			if( elementType.IsComponentType )
			{
				elementPropertyMapping = new CompositeElementPropertyMapping( elementColumnNames, ( IAbstractComponentType ) elementType, factory );
			}
			else if( !elementType.IsEntityType )
			{
				elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType );
			}
			else
			{
				IClassPersister persister = factory.GetPersister( ( ( EntityType ) elementType ).AssociatedClass );
				// Not all classpersisters implement IPropertyMapping!
				if( persister is IPropertyMapping )
				{
					elementPropertyMapping = ( IPropertyMapping ) persister;
				}
				else
				{
					elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType );
				}
			}
		}
		protected override JoinType GetJoinType(
			IAssociationType type,
			OuterJoinFetchStrategy config,
			string path,
			string table,
			string[ ] foreignKeyColumns,
			ISessionFactoryImplementor factory
			)
		{
			JoinType joinType = base.GetJoinType( type, config, path, table, foreignKeyColumns, factory );
			// We can use an inner-join for the many-to-many
			if( joinType == JoinType.LeftOuterJoin && string.Empty.Equals( path ) )
			{
				joinType = JoinType.InnerJoin;
			}
			return joinType;
		}
		/// <summary>
		/// Does the mapping, and Hibernate default semantics, specify that
		/// this association should be fetched by outer joining
		/// </summary>
		/// <param name="config"></param>
		/// <param name="type"></param>
		/// <param name="factory"></param>
		/// <returns></returns>
		protected bool IsJoinedFetchEnabledByDefault( OuterJoinFetchStrategy config, IAssociationType type, ISessionFactoryImplementor factory )
		{
			if ( !type.IsEntityType && !type.IsPersistentCollectionType )
			{
				return false;
			}
			else
			{
				switch ( config )
				{
					case OuterJoinFetchStrategy.Eager:
						return true;

					case OuterJoinFetchStrategy.Lazy:
						return false;

					case OuterJoinFetchStrategy.Auto:
						if ( !factory.IsOuterJoinedFetchEnabled )
						{
							return false;
						}
						if ( type.IsEntityType )
						{
							EntityType entityType = type as EntityType;
							IClassPersister persister = factory.GetPersister( entityType.AssociatedClass );
							return !persister.HasProxy || (
								entityType.IsOneToOne &&
								( (OneToOneType) entityType).IsNullable
								);
						}
						else
						{
							return false;
						}

					default:
						throw new ArgumentOutOfRangeException( "config", config, "Unknown OJ strategy " + config.ToString() );
				}
			}
		}
예제 #12
0
        public AbstractCollectionPersister(Mapping.Collection collection, ISessionFactoryImplementor factory)
        {
            this.factory = factory;
            dialect      = factory.Dialect;
            //sqlExceptionConverter = factory.SQLExceptionConverter;
            collectionType = collection.CollectionType;
            role           = collection.Role;
            ownerClass     = collection.OwnerClass;
            Alias alias = new Alias("__");

            sqlOrderByString         = collection.OrderBy;
            hasOrder                 = sqlOrderByString != null;
            sqlOrderByStringTemplate = hasOrder ? Template.RenderOrderByStringTemplate(sqlOrderByString, dialect) : null;

            sqlWhereString         = collection.Where;
            hasWhere               = sqlWhereString != null;
            sqlWhereStringTemplate = hasWhere ? Template.RenderWhereStringTemplate(sqlWhereString, dialect) : null;

            hasOrphanDelete = collection.OrphanDelete;

            batchSize = collection.BatchSize;

            cache = collection.Cache;

            keyType = collection.Key.Type;
            int keySpan = collection.Key.ColumnSpan;

            keyColumnNames = new string[keySpan];
            string[] keyAliases = new string[keySpan];
            int      k          = 0;

            foreach (Column col in collection.Key.ColumnCollection)
            {
                keyColumnNames[k] = col.GetQuotedName(dialect);
                keyAliases[k]     = col.Alias(dialect);
                k++;
            }
            keyColumnAliases = alias.ToAliasStrings(keyAliases, dialect);
            //unquotedKeyColumnNames = StringHelper.Unquote( keyColumnAliases );
            ISet distinctColumns = new HashedSet();

            CheckColumnDuplication(distinctColumns, collection.Key.ColumnCollection);

            //isSet = collection.IsSet;
            //isSorted = collection.IsSorted;
            primitiveArray = collection.IsPrimitiveArray;
            array          = collection.IsArray;

            IValue      element     = collection.Element;
            int         elementSpan = element.ColumnSpan;
            ICollection iter        = element.ColumnCollection;
            Table       table       = collection.CollectionTable;

            enableJoinedFetch = element.OuterJoinFetchSetting;
            elementType       = element.Type;

            if (!collection.IsOneToMany)
            {
                CheckColumnDuplication(distinctColumns, element.ColumnCollection);
            }

            if (elementType.IsEntityType)
            {
                elementPersister = factory.GetPersister((( EntityType )elementType).AssociatedClass);
            }
            else
            {
                elementPersister = null;
            }

            qualifiedTableName = table.GetQualifiedName(dialect, factory.DefaultSchema);
            string[] aliases = new string[elementSpan];
            elementColumnNames = new string[elementSpan];
            int j = 0;

            foreach (Column col in iter)
            {
                elementColumnNames[j] = col.GetQuotedName(dialect);
                aliases[j]            = col.Alias(dialect);
                j++;
            }

            elementColumnAliases = alias.ToAliasStrings(aliases, dialect);

            IType selectColumns;

            string[] selectType;

            hasIndex = collection.IsIndexed;

            if (hasIndex)
            {
                IndexedCollection indexedCollection = ( IndexedCollection )collection;

                indexType = indexedCollection.Index.Type;
                int indexSpan = indexedCollection.Index.ColumnSpan;
                indexColumnNames = new string[indexSpan];

                string[] indexAliases = new string[indexSpan];
                int      i            = 0;
                foreach (Column indexCol in indexedCollection.Index.ColumnCollection)
                {
                    indexAliases[i]     = indexCol.Alias(dialect);
                    indexColumnNames[i] = indexCol.GetQuotedName(dialect);
                    i++;
                }
                selectType         = indexColumnNames;
                selectColumns      = indexType;
                indexColumnAliases = alias.ToAliasStrings(indexAliases, dialect);
                CheckColumnDuplication(distinctColumns, indexedCollection.Index.ColumnCollection);
            }
            else
            {
                indexType          = null;
                indexColumnNames   = null;
                indexColumnAliases = null;
                selectType         = elementColumnNames;
                selectColumns      = elementType;
            }

            hasIdentifier = collection.IsIdentified;

            if (hasIdentifier)
            {
                if (collection.IsOneToMany)
                {
                    throw new MappingException("one-to-many collections with identifiers are not supported.");
                }
                IdentifierCollection idColl = ( IdentifierCollection )collection;
                identifierType = idColl.Identifier.Type;

                Column col = null;
                foreach (Column column in idColl.Identifier.ColumnCollection)
                {
                    col = column;
                    break;
                }

                identifierColumnName         = col.GetQuotedName(dialect);
                selectType                   = new string[] { identifierColumnName };
                selectColumns                = identifierType;
                identifierColumnAlias        = alias.ToAliasString(col.Alias(dialect), dialect);
                unquotedIdentifierColumnName = identifierColumnAlias;
                identifierGenerator          = idColl.Identifier.CreateIdentifierGenerator(dialect);
                CheckColumnDuplication(distinctColumns, idColl.Identifier.ColumnCollection);
            }
            else
            {
                identifierType               = null;
                identifierColumnName         = null;
                identifierColumnAlias        = null;
                unquotedIdentifierColumnName = null;
                identifierGenerator          = null;
            }

            rowSelectColumnNames = selectType;
            rowSelectType        = selectColumns;

            sqlDeleteString    = GenerateDeleteString();
            sqlInsertRowString = GenerateInsertRowString();
            sqlUpdateRowString = GenerateUpdateRowString();
            sqlDeleteRowString = GenerateDeleteRowString();
            isLazy             = collection.IsLazy;

            isInverse = collection.IsInverse;

            if (collection.IsArray)
            {
                elementClass = (( Array )collection).ElementClass;
            }
            else
            {
                // for non-arrays, we don't need to know the element class
                elementClass = null;
            }

            initializer = CreateCollectionInitializer(factory);

            if (elementType.IsComponentType)
            {
                elementPropertyMapping = new CompositeElementPropertyMapping(elementColumnNames, ( IAbstractComponentType )elementType, factory);
            }
            else if (!elementType.IsEntityType)
            {
                elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
            }
            else
            {
                IClassPersister persister = factory.GetPersister((( EntityType )elementType).AssociatedClass);
                // Not all classpersisters implement IPropertyMapping!
                if (persister is IPropertyMapping)
                {
                    elementPropertyMapping = ( IPropertyMapping )persister;
                }
                else
                {
                    elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
                }
            }
        }
		protected override JoinType GetJoinType(
			IAssociationType type,
			OuterJoinFetchStrategy config,
			string path,
			string table,
			string[] foreignKeyColumns,
			ISessionFactoryImplementor factory )
		{
			if ( criteria.IsJoin( path ) )
			{
				return JoinType.InnerJoin;
			}
			else
			{
				FetchMode fm = criteria.GetFetchMode( path );
				//fm==null ||  - an Enum can't be null
				if( fm == FetchMode.Default )
				{
					return base.GetJoinType( type, config, path, table, foreignKeyColumns, factory );
				}
				else
				{
					return fm == FetchMode.Eager ? JoinType.LeftOuterJoin : JoinType.None;
				}
			}
		}