Exemple #1
0
        /// <summary>
        /// Load an instance by a unique key that is not the primary key.
        /// </summary>
        /// <param name="entityName">The name of the entity to load </param>
        /// <param name="uniqueKeyPropertyName">The name of the property defining the unique key. </param>
        /// <param name="key">The unique key property value. </param>
        /// <param name="session">The originating session. </param>
        /// <returns> The loaded entity </returns>
        public object LoadByUniqueKey(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session)
        {
            ISessionFactoryImplementor factory   = session.Factory;
            IUniqueKeyLoadable         persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

            //TODO: implement caching?! proxies?!

            EntityUniqueKey euk =
                new EntityUniqueKey(entityName, uniqueKeyPropertyName, key, GetIdentifierOrUniqueKeyType(factory),
                                    session.EntityMode, session.Factory);

            IPersistenceContext persistenceContext = session.PersistenceContext;

            try
            {
                object result = persistenceContext.GetEntity(euk);
                if (result == null)
                {
                    result = persister.LoadByUniqueKey(uniqueKeyPropertyName, key, session);
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }
        /// <summary>
        /// Create an action that will evict collection and entity regions based on queryspaces (table names).
        /// </summary>
        public BulkOperationCleanupAction(ISessionImplementor session, ISet <string> querySpaces)
        {
            //from H3.2 TODO: cache the autodetected information and pass it in instead.
            this.session = session;

            ISet <string> tmpSpaces = new HashedSet <string>(querySpaces);
            ISessionFactoryImplementor           factory = session.Factory;
            IDictionary <string, IClassMetadata> acmd    = factory.GetAllClassMetadata();

            foreach (KeyValuePair <string, IClassMetadata> entry in acmd)
            {
                string           entityName   = entry.Key;
                IEntityPersister persister    = factory.GetEntityPersister(entityName);
                string[]         entitySpaces = persister.QuerySpaces;

                if (AffectedEntity(querySpaces, entitySpaces))
                {
                    if (persister.HasCache)
                    {
                        affectedEntityNames.Add(persister.EntityName);
                    }
                    ISet <string> roles = session.Factory.GetCollectionRolesByEntityParticipant(persister.EntityName);
                    if (roles != null)
                    {
                        affectedCollectionRoles.AddAll(roles);
                    }
                    for (int y = 0; y < entitySpaces.Length; y++)
                    {
                        tmpSpaces.Add(entitySpaces[y]);
                    }
                }
            }
            spaces = new List <string>(tmpSpaces);
        }
Exemple #3
0
        protected virtual IEntityPersister GetEntityPersister(ISessionFactoryImplementor factory, string entityName)
        {
            // Check for an exact match.
            IEntityPersister persister = factory.TryGetEntityPersister(entityName);

            if (persister != null)
            {
                return(persister);
            }

            // Couldn't find persister through exact name, try finding a single implementing class.
            string[] implementors = factory.GetImplementors(entityName);
            if (implementors.Length > 1)
            {
                var messageBuilder = new StringBuilder(512);
                messageBuilder.AppendLine(string.Format("Ambiguous persister for {0} implemented by more than one hierarchy: ",
                                                        entityName));
                Array.ForEach(implementors, s => messageBuilder.AppendLine(s));

                throw new HibernateException(messageBuilder.ToString());
            }
            if (implementors.Length == 0)
            {
                return(null);
            }
            return(factory.GetEntityPersister(implementors[0]));
        }
Exemple #4
0
        public override string ToLoggableString(object value, ISessionFactoryImplementor factory)
        {
            if (value == null)
            {
                return("null");
            }

            IEntityPersister persister = factory.GetEntityPersister(associatedEntityName);
            StringBuilder    result    = new StringBuilder().Append(associatedEntityName);

            if (persister.HasIdentifierProperty)
            {
                EntityMode?entityMode = persister.GuessEntityMode(value);
                object     id;
                if (!entityMode.HasValue)
                {
                    if (isEmbeddedInXML)
                    {
                        throw new InvalidCastException(value.GetType().FullName);
                    }

                    id = value;
                }
                else
                {
                    id = GetIdentifier(value, persister, entityMode.Value);
                }

                result.Append('#').Append(persister.IdentifierType.ToLoggableString(id, factory));
            }

            return(result.ToString());
        }
        private static bool TryGetEntityPersister(
            string currentEntityName,
            System.Type convertedType,
            ISessionFactoryImplementor sessionFactory,
            out IEntityPersister persister)
        {
            var currentEntityPersister = sessionFactory.TryGetEntityPersister(currentEntityName);

            if (currentEntityPersister == null)
            {
                // When dealing with a polymorphic query it is not important which entity name we pick
                // as they all need to have the same mapped types for members of the type that is queried.
                // If one of the entites has a different type mapped (e.g. enum mapped as string instead of numeric),
                // the query will fail to execute as currently the ParameterMetadata is bound to IQueryPlan and not to IQueryTranslator
                // (e.g. s.Query<IEntity>().Where(a => a.MyEnum == MyEnum.Option)).
                currentEntityName = sessionFactory.GetImplementors(currentEntityName).FirstOrDefault();
                if (currentEntityName == null)
                {
                    persister = null;
                    return(false);
                }

                currentEntityPersister = sessionFactory.GetEntityPersister(currentEntityName);
            }

            return(TryGetEntityPersister(currentEntityPersister, convertedType, sessionFactory, out persister));
        }
Exemple #6
0
        protected IQueryableCollection GetQueryableCollection(string entityName, string actualPropertyName,
                                                              ISessionFactoryImplementor factory)
        {
            IPropertyMapping ownerMapping = (IPropertyMapping)factory.GetEntityPersister(entityName);
            IType            type         = ownerMapping.ToType(actualPropertyName);

            if (!type.IsCollectionType)
            {
                throw new MappingException(
                          "Property path [" + entityName + "." + actualPropertyName + "] does not reference a collection"
                          );
            }

            string role = ((CollectionType)type).Role;

            try
            {
                return((IQueryableCollection)factory.GetCollectionPersister(role));
            }
            catch (InvalidCastException cce)
            {
                throw new QueryException("collection role is not queryable: " + role, cce);
            }
            catch (Exception e)
            {
                throw new QueryException("collection role not found: " + role, e);
            }
        }
Exemple #7
0
        public SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            string entityName         = criteriaQuery.GetEntityName(criteria, propertyName);
            string actualPropertyName = criteriaQuery.GetPropertyName(propertyName);
            string sqlAlias           = criteriaQuery.GetSQLAlias(criteria, propertyName);

            ISessionFactoryImplementor factory             = criteriaQuery.Factory;
            IQueryableCollection       collectionPersister = GetQueryableCollection(entityName, actualPropertyName, factory);

            string[] collectionKeys = collectionPersister.KeyColumnNames;
            string[] ownerKeys      = ((ILoadable)factory.GetEntityPersister(entityName)).IdentifierColumnNames;

            StringBuilder innerSelect = new StringBuilder();

            innerSelect.Append("(select 1 from ")
            .Append(collectionPersister.TableName)
            .Append(" where ")
            .Append(
                new ConditionalFragment().SetTableAlias(sqlAlias).SetCondition(ownerKeys, collectionKeys).ToSqlStringFragment());
            if (collectionPersister.HasWhere)
            {
                innerSelect.Append(" and (")
                .Append(collectionPersister.GetSQLWhereString(collectionPersister.TableName))
                .Append(") ");
            }

            innerSelect.Append(")");

            return(new SqlString(new string[] { ExcludeEmpty ? "exists" : "not exists", innerSelect.ToString() }));
        }
        private IEntityPersister ResolvePersister(string entityName)
        {
            // Check for an exact match.

            var persister = _sessionFactory.TryGetEntityPersister(entityName);

            if (persister != null)
            {
                return(persister);
            }

            // Couldn't find persister through exact name, try finding a single implementing class.

            string[] implementors = _sessionFactory.GetImplementors(entityName);

            if (implementors.Length > 1)
            {
                throw new ODataException(String.Format(ErrorMessages.ODataRequest_AmbiguousEntityName, entityName));
            }
            else if (implementors.Length == 0)
            {
                return(null);
            }
            else
            {
                return(_sessionFactory.GetEntityPersister(implementors[0]));
            }
        }
		public override bool IsEqual(object x, object y, EntityMode entityMode, ISessionFactoryImplementor factory)
		{
			IEntityPersister persister = factory.GetEntityPersister(associatedEntityName);
			if (!persister.CanExtractIdOutOfEntity)
			{
				return base.IsEqual(x, y, entityMode);
			}

			object xid;
			
			if (x.IsProxy())
			{
				INHibernateProxy proxy = x as INHibernateProxy; 
				xid = proxy.HibernateLazyInitializer.Identifier;
			}
			else
			{
				xid = persister.GetIdentifier(x, entityMode);
			}

			object yid;
			
			if (y.IsProxy())
			{
				INHibernateProxy proxy = y as INHibernateProxy; 
				yid = proxy.HibernateLazyInitializer.Identifier;
			}
			else
			{
				yid = persister.GetIdentifier(y, entityMode);
			}

			return persister.IdentifierType.IsEqual(xid, yid, entityMode, factory);
		}
Exemple #10
0
        public override bool IsEqual(object x, object y, ISessionFactoryImplementor factory)
        {
            IEntityPersister persister = factory.GetEntityPersister(associatedEntityName);

            if (!persister.CanExtractIdOutOfEntity)
            {
                return(base.IsEqual(x, y));
            }

            object xid;

            if (x.IsProxy())
            {
                INHibernateProxy proxy = x as INHibernateProxy;
                xid = proxy.HibernateLazyInitializer.Identifier;
            }
            else
            {
                xid = persister.GetIdentifier(x);
            }

            object yid;

            if (y.IsProxy())
            {
                INHibernateProxy proxy = y as INHibernateProxy;
                yid = proxy.HibernateLazyInitializer.Identifier;
            }
            else
            {
                yid = persister.GetIdentifier(y);
            }

            return(persister.IdentifierType.IsEqual(xid, yid, factory));
        }
Exemple #11
0
        public static Type GetRootType(ICriteria criteria)
        {
            Type rootType = criteria.GetRootEntityTypeIfAvailable();

            if (rootType != null)
            {
                return(rootType);
            }

            CriteriaImpl impl = GetRootCriteria(criteria);

            if (impl.Session == null)
            {
                throw new InvalidOperationException("Could not get root type on criteria that is not attached to a session");
            }

            ISessionFactoryImplementor factory   = impl.Session.Factory;
            IEntityPersister           persister = factory.GetEntityPersister(impl.EntityOrClassName);

            if (persister == null)
            {
                throw new InvalidOperationException("Could not find entity named: " + impl.EntityOrClassName);
            }

            return(persister.GetMappedClass(EntityMode.Poco));
        }
		protected IQueryableCollection GetQueryableCollection(string entityName, string actualPropertyName,
		                                                      ISessionFactoryImplementor factory)
		{
			IPropertyMapping ownerMapping = (IPropertyMapping) factory.GetEntityPersister(entityName);
			IType type = ownerMapping.ToType(actualPropertyName);
			if (!type.IsCollectionType)
			{
				throw new MappingException(
					"Property path [" + entityName + "." + actualPropertyName + "] does not reference a collection"
					);
			}

			string role = ((CollectionType) type).Role;
			try
			{
				return (IQueryableCollection) factory.GetCollectionPersister(role);
			}
			catch (InvalidCastException cce)
			{
				throw new QueryException("collection role is not queryable: " + role, cce);
			}
			catch (Exception e)
			{
				throw new QueryException("collection role not found: " + role, e);
			}
		}
Exemple #13
0
        /// <summary>
        /// Does the mapping, and Hibernate default semantics, specify that
        /// this association should be fetched by outer joining
        /// </summary>
        protected bool IsJoinedFetchEnabledInMapping(FetchMode config, IAssociationType type)
        {
            if (!type.IsEntityType && !type.IsCollectionType)
            {
                return(false);
            }
            else
            {
                switch (config)
                {
                case FetchMode.Join:
                    return(true);

                case FetchMode.Select:
                    return(false);

                case FetchMode.Default:
                    if (type.IsEntityType)
                    {
                        //TODO: look at the owning property and check that it
                        //      isn't lazy (by instrumentation)
                        EntityType       entityType = (EntityType)type;
                        IEntityPersister persister  = factory.GetEntityPersister(entityType.GetAssociatedEntityName());
                        return(!persister.HasProxy);
                    }
                    else
                    {
                        return(false);
                    }

                default:
                    throw new ArgumentOutOfRangeException("config", config, "Unknown OJ strategy " + config);
                }
            }
        }
Exemple #14
0
        public static string GenerateSQL(ICriteria criteria)
        {
            var criteriaImpl = (CriteriaImpl)criteria;
            ISessionImplementor        session = criteriaImpl.Session;
            ISessionFactoryImplementor factory = session.Factory;

            var translator =
                new CriteriaQueryTranslator(
                    factory,
                    criteriaImpl,
                    criteriaImpl.EntityOrClassName,
                    CriteriaQueryTranslator.RootSqlAlias);

            String[] implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName);

            var walker = new CriteriaJoinWalker(
                (IOuterJoinLoadable)factory.GetEntityPersister(implementors[0]),
                translator,
                factory,
                criteriaImpl,
                criteriaImpl.EntityOrClassName,
                session.EnabledFilters);

            return(walker.SqlString.ToString());
        }
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            ISessionFactoryImplementor factory = criteriaQuery.Factory;

            var innerQuery = new CriteriaQueryTranslator(
                factory,
                criteriaImpl,                 //implicit polymorphism not supported (would need a union)
                criteriaImpl.EntityOrClassName,
                criteriaQuery.GenerateSQLAlias(),
                criteriaQuery);

            types = innerQuery.HasProjection ? innerQuery.ProjectedTypes : null;

            if (innerQuery.HasProjection == false)
            {
                throw new QueryException("Cannot use subqueries on a criteria without a projection.");
            }

            IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

            //patch to generate joins on subqueries
            //stolen from CriteriaLoader
            CriteriaJoinWalker walker =
                new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

            parameters = innerQuery.GetQueryParameters();             // parameters can be inferred only after initialize the walker

            SqlString sql = walker.SqlString;

            if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
            {
                int?      offset          = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect);
                int?      limit           = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect);
                Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null;
                Parameter limitParameter  = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null;
                sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter);
            }

            SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));

            if (op != null)
            {
                buf.Add(" ").Add(op).Add(" ");
            }

            if (quantifier != null && prefixOp)
            {
                buf.Add(quantifier).Add(" ");
            }

            buf.Add("(").Add(sql).Add(")");

            if (quantifier != null && prefixOp == false)
            {
                buf.Add(" ").Add(quantifier);
            }

            return(buf.ToSqlString());
        }
Exemple #16
0
 protected override Expression VisitConstant(ConstantExpression node)
 {
     if (node.Value is IQueryable queryable)
     {
         var persister = _sessionFactoryImplementor.GetEntityPersister(queryable.ElementType.FullName);
     }
     return(node);
 }
        private Persister.Entity.IJoinable GetPathJoinable(string path)
        {
            // start with the root
            IJoinable last = rootPersister;

            var tokens = path.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

            if (tokens.Length == 0)
            {
                return(last);
            }

            IPropertyMapping lastEntity = rootPersister;
            int i = 0;

            if (entityJoins.TryGetValue(tokens[0], out var entityJoinInfo))
            {
                last       = entityJoinInfo.Persister;
                lastEntity = (IPropertyMapping)last;
                i++;
            }

            string componentPath = string.Empty;

            for (; i < tokens.Length; i++)
            {
                componentPath += tokens[i];
                IType type = lastEntity.ToType(componentPath);
                if (type.IsAssociationType)
                {
                    if (type.IsCollectionType)
                    {
                        // ignore joinables for composite collections
                        var collectionType = (CollectionType)type;
                        var persister      = Factory.GetCollectionPersister(collectionType.Role);
                        if (persister.ElementType.IsEntityType == false)
                        {
                            return(null);
                        }
                    }
                    IAssociationType atype = (IAssociationType)type;

                    last          = atype.GetAssociatedJoinable(Factory);
                    lastEntity    = (NHibernate_Persister_Entity.IPropertyMapping)Factory.GetEntityPersister(atype.GetAssociatedEntityName(Factory));
                    componentPath = "";
                }
                else if (type.IsComponentType)
                {
                    componentPath += '.';
                }
                else
                {
                    throw new QueryException("not an association: " + componentPath);
                }
            }
            return(last);
        }
Exemple #18
0
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            InitializeInnerQueryAndParameters(criteriaQuery);

            if (innerQuery.HasProjection == false)
            {
                throw new QueryException("Cannot use subqueries on a criteria without a projection.");
            }

            ISessionFactoryImplementor factory = criteriaQuery.Factory;

            IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

            //patch to generate joins on subqueries
            //stolen from CriteriaLoader
            CriteriaJoinWalker walker =
                new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

            parameters = innerQuery.GetQueryParameters();             // parameters can be inferred only after initialize the walker

            SqlString sql = walker.SqlString;

            if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
            {
                int?      offset          = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect);
                int?      limit           = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect);
                Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null;
                Parameter limitParameter  = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null;
                sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter);
            }

            // during CriteriaImpl.Clone we are doing a shallow copy of each criterion.
            // this is not a problem for common criterion but not for SubqueryExpression because here we are holding the state of inner CriteriaTraslator (ICriteriaQuery).
            // After execution (ToSqlString) we have to clean the internal state because the next execution may be performed in a different tree reusing the same istance of SubqueryExpression.
            innerQuery = null;

            SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));

            if (op != null)
            {
                buf.Add(" ").Add(op).Add(" ");
            }

            if (quantifier != null && prefixOp)
            {
                buf.Add(quantifier).Add(" ");
            }

            buf.Add("(").Add(sql).Add(")");

            if (quantifier != null && prefixOp == false)
            {
                buf.Add(" ").Add(quantifier);
            }

            return(buf.ToSqlString());
        }
Exemple #19
0
        public void NotIgnoreSqlTypeDef()
        {
            var pc = factory.GetEntityPersister(typeof(MultiTypeEntity).FullName);

            var type = pc.GetPropertyType("StringProp");

            Assert.That(type.SqlTypes(factory)[0].Length, Is.EqualTo(100));

            type = pc.GetPropertyType("AnsiStringProp");
            Assert.That(type.SqlTypes(factory)[0].Length, Is.EqualTo(101));

            type = pc.GetPropertyType("Decimal");
            Assert.That(type.SqlTypes(factory)[0].Precision, Is.EqualTo(5));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(2));

            type = pc.GetPropertyType("Currency");
            Assert.That(type.SqlTypes(factory)[0].Precision, Is.EqualTo(10));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(3));

            type = pc.GetPropertyType("Double");
            Assert.That(type.SqlTypes(factory)[0].Precision, Is.EqualTo(11));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(4));

            type = pc.GetPropertyType("Float");
            Assert.That(type.SqlTypes(factory)[0].Precision, Is.EqualTo(6));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(3));

            type = pc.GetPropertyType("BinaryBlob");
            Assert.That(type.SqlTypes(factory)[0].Length, Is.EqualTo(1000));

            type = pc.GetPropertyType("Binary");
            Assert.That(type.SqlTypes(factory)[0].Length, Is.EqualTo(1001));

            type = pc.GetPropertyType("StringClob");
            Assert.That(type.SqlTypes(factory)[0].Length, Is.EqualTo(1002));

            type = pc.GetPropertyType(nameof(MultiTypeEntity.DateTimeProp));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(0), "Unexpected scale for DateTimeProp");
            Assert.That(type.SqlTypes(factory)[0].ScaleDefined, Is.True);

            type = pc.GetPropertyType(nameof(MultiTypeEntity.LocalDateTime));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(1), "Unexpected scale for LocalDateTime");

            type = pc.GetPropertyType(nameof(MultiTypeEntity.UtcDateTime));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(2), "Unexpected scale for UtcDateTime");

            type = pc.GetPropertyType(nameof(MultiTypeEntity.TimeProp));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(3), "Unexpected scale for TimeProp");

            type = pc.GetPropertyType(nameof(MultiTypeEntity.TimeAsTimeSpan));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(4), "Unexpected scale for TimeAsTimeSpan");

            type = pc.GetPropertyType(nameof(MultiTypeEntity.DateTimeOffsetProp));
            Assert.That(type.SqlTypes(factory)[0].Scale, Is.EqualTo(5), "Unexpected scale for DateTimeOffsetProp");
        }
        private IJoinable GetPathJoinable(string path)
        {
            IJoinable        last       = (IJoinable)Factory.GetEntityPersister(rootEntityName);
            IPropertyMapping lastEntity = (IPropertyMapping)last;

            string componentPath = "";

            StringTokenizer tokens = new StringTokenizer(path, ".", false);

            foreach (string token in tokens)
            {
                componentPath += token;
                IType type = lastEntity.ToType(componentPath);
                if (type.IsAssociationType)
                {
                    if (type.IsCollectionType)
                    {
                        // ignore joinables for composite collections
                        var collectionType = (CollectionType)type;
                        var persister      = Factory.GetCollectionPersister(collectionType.Role);
                        if (persister.ElementType.IsEntityType == false)
                        {
                            return(null);
                        }
                    }
                    IAssociationType atype = (IAssociationType)type;

                    last          = atype.GetAssociatedJoinable(Factory);
                    lastEntity    = (IPropertyMapping)Factory.GetEntityPersister(atype.GetAssociatedEntityName(Factory));
                    componentPath = "";
                }
                else if (type.IsComponentType)
                {
                    componentPath += '.';
                }
                else
                {
                    throw new QueryException("not an association: " + componentPath);
                }
            }
            return(last);
        }
        private ISqlLoadable GetSQLLoadable(string entityName)
        {
            IEntityPersister persister = factory.GetEntityPersister(entityName);
            var persisterAsSqlLoadable = persister as ISqlLoadable;

            if (persisterAsSqlLoadable == null)
            {
                throw new MappingException("class persister is not ISqlLoadable: " + entityName);
            }
            return(persisterAsSqlLoadable);
        }
		public static IQueryable FindQueryableUsingImports(ISessionFactoryImplementor sfi, string className)
		{
			string importedClassName = sfi.GetImportedClassName(className);

			if (importedClassName == null)
			{
				return null;
			}

			return (IQueryable) sfi.GetEntityPersister(importedClassName, false);
		}
        /// <summary>
        /// Locate the persister by class or entity name.
        /// </summary>
        /// <param name="name">The class or entity name</param>
        /// <returns>The defined persister for this entity, or null if none found.</returns>
        private IEntityPersister FindEntityPersisterByName(String name)
        {
            // First, try to get the persister using the given name directly.
            try
            {
                return(sfi.GetEntityPersister(name));
            }
            catch (MappingException ignore)
            {
                // unable to locate it using this name
            }

            // If that didn't work, try using the 'import' name.
            String importedClassName = sfi.GetImportedClassName(name);

            if (importedClassName == null)
            {
                return(null);
            }
            return(sfi.GetEntityPersister(importedClassName));
        }
Exemple #24
0
        private static System.Type GetRootType(DetachedCriteria criteria, ISession session)
        {
            ISessionFactoryImplementor factory   = (ISessionFactoryImplementor)session.SessionFactory;
            IEntityPersister           persister = factory.GetEntityPersister(criteria.EntityOrClassName);

            if (persister == null)
            {
                throw new InvalidOperationException("Could not find entity named: " + criteria.EntityOrClassName);
            }

            return(persister.GetMappedClass(EntityMode.Poco));
        }
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            InitializeInnerQueryAndParameters(criteriaQuery);

            if (innerQuery.HasProjection == false)
            {
                throw new QueryException("Cannot use subqueries on a criteria without a projection.");
            }

            ISessionFactoryImplementor factory = criteriaQuery.Factory;

            IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

            //buffer needs to be before CriteriaJoinWalker for sake of parameter order
            SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));

            //patch to generate joins on subqueries
            //stolen from CriteriaLoader
            CriteriaJoinWalker walker =
                new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

            SqlString sql = walker.SqlString;

            if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
            {
                int firstResults         = Loader.Loader.GetFirstRow(parameters.RowSelection);
                int maxResults           = Loader.Loader.GetMaxOrLimit(factory.Dialect, parameters.RowSelection);
                int?offsetParameterIndex = criteriaQuery.CreatePagingParameter(firstResults);
                int?limitParameterIndex  = criteriaQuery.CreatePagingParameter(maxResults);
                sql = factory.Dialect.GetLimitString(sql, firstResults, maxResults, offsetParameterIndex, limitParameterIndex);
            }

            if (op != null)
            {
                buf.Add(" ").Add(op).Add(" ");
            }

            if (quantifier != null && prefixOp)
            {
                buf.Add(quantifier).Add(" ");
            }

            buf.Add("(").Add(sql).Add(")");

            if (quantifier != null && prefixOp == false)
            {
                buf.Add(" ").Add(quantifier);
            }

            return(buf.ToSqlString());
        }
Exemple #26
0
        private object AssembleCacheEntry(CacheEntry entry, object id, IEntityPersister persister, LoadEvent @event)
        {
            object       optionalObject        = @event.InstanceToLoad;
            IEventSource session               = @event.Session;
            ISessionFactoryImplementor factory = session.Factory;

            if (log.IsDebugEnabled)
            {
                log.Debug("assembling entity from second-level cache: " + MessageHelper.InfoString(persister, id, factory));
            }

            IEntityPersister subclassPersister = factory.GetEntityPersister(entry.Subclass);
            object           result            = optionalObject ?? session.Instantiate(subclassPersister, id);

            // make it circular-reference safe
            TwoPhaseLoad.AddUninitializedCachedEntity(new EntityKey(id, subclassPersister, session.EntityMode), result, subclassPersister, LockMode.None, entry.AreLazyPropertiesUnfetched, entry.Version, session);

            IType[]  types  = subclassPersister.PropertyTypes;
            object[] values = entry.Assemble(result, id, subclassPersister, session.Interceptor, session);             // intializes result by side-effect
            TypeFactory.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session);

            object version = Versioning.GetVersion(values, subclassPersister);

            if (log.IsDebugEnabled)
            {
                log.Debug("Cached Version: " + version);
            }

            IPersistenceContext persistenceContext = session.PersistenceContext;

            persistenceContext.AddEntry(result, Status.Loaded, values, null, id, version, LockMode.None, true, subclassPersister, false, entry.AreLazyPropertiesUnfetched);
            subclassPersister.AfterInitialize(result, entry.AreLazyPropertiesUnfetched, session);
            persistenceContext.InitializeNonLazyCollections();
            // upgrade the lock if necessary:
            //lock(result, lockMode);

            //PostLoad is needed for EJB3
            //TODO: reuse the PostLoadEvent...
            PostLoadEvent postLoadEvent = new PostLoadEvent(session);

            postLoadEvent.Entity    = result;
            postLoadEvent.Id        = id;
            postLoadEvent.Persister = persister;

            IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners;
            for (int i = 0; i < listeners.Length; i++)
            {
                listeners[i].OnPostLoad(postLoadEvent);
            }
            return(result);
        }
 public void SetupTest()
 {
     _session   = Substitute.For <ISessionImplementor>();
     _factory   = Substitute.For <ISessionFactoryImplementor>();
     _persister = Substitute.For <IEntityPersister>();
     _session.Factory.Returns(_factory);
     _factory.GetAllClassMetadata().Returns(new Dictionary <string, IClassMetadata> {
         ["TestClass"] = null
     });
     _factory.GetEntityPersister("TestClass").Returns(_persister);
     _factory.GetCollectionRolesByEntityParticipant("TestClass").Returns(new HashSet <string>(new[] { "TestClass.Children" }));
     _persister.QuerySpaces.Returns(new[] { "TestClass" });
     _persister.EntityName.Returns("TestClass");
 }
		public object Destructure(object item, ISessionFactoryImplementor factory)
		{
			IDictionary map = (IDictionary)item;
			bool lazyPropertiesUnfetched = ((bool)map["_lazyPropertiesUnfetched"]);
			string subclass = (string)map["_subclass"];
			object version = map["_version"];
			IEntityPersister subclassPersister = factory.GetEntityPersister(subclass);
			string[] names = subclassPersister.PropertyNames;
			object[] state = new object[names.Length];
			for (int i = 0; i < names.Length; i++)
			{
				state[i] = map[names[i]];
			}
			return new CacheEntry(state, subclass, lazyPropertiesUnfetched, version);
		}
        private void CreateCriteriaEntityNameMap()
        {
            // initialize the rootProvider first
            ICriteriaInfoProvider rootProvider = new EntityCriteriaInfoProvider((IQueryable)sessionFactory.GetEntityPersister(rootEntityName));

            criteriaInfoMap.Add(rootCriteria, rootProvider);
            nameCriteriaInfoMap.Add(rootProvider.Name, rootProvider);


            foreach (KeyValuePair <string, ICriteria> me in associationPathCriteriaMap)
            {
                ICriteriaInfoProvider info = GetPathInfo(me.Key);
                criteriaInfoMap.Add(me.Value, info);
                nameCriteriaInfoMap[info.Name] = info;
            }
        }
        public object Destructure(object item, ISessionFactoryImplementor factory)
        {
            IDictionary      map = (IDictionary)item;
            bool             lazyPropertiesUnfetched = ((bool)map["_lazyPropertiesUnfetched"]);
            string           subclass          = (string)map["_subclass"];
            object           version           = map["_version"];
            IEntityPersister subclassPersister = factory.GetEntityPersister(subclass);

            string[] names = subclassPersister.PropertyNames;
            object[] state = new object[names.Length];
            for (int i = 0; i < names.Length; i++)
            {
                state[i] = map[names[i]];
            }
            return(new CacheEntry(state, subclass, lazyPropertiesUnfetched, version));
        }
        public static IDictionary <System.Type, string> GetProxyMetaData(this ISessionFactoryImplementor factory, IDictionary <string, IClassMetadata> metaData)
        {
            var dict = new Dictionary <System.Type, string>();

            foreach (var item in metaData)
            {
                if (item.Value.HasProxy)
                {
                    var proxyType = factory.GetEntityPersister(item.Key).GetConcreteProxyClass(EntityMode.Poco);
                    if (proxyType != item.Value.GetMappedClass(EntityMode.Poco) && !dict.ContainsKey(proxyType))
                    {
                        dict.Add(proxyType, item.Key);
                    }
                }
            }
            return(dict);
        }
Exemple #32
0
        /// <summary>
        /// Load an instance by a unique key that is not the primary key.
        /// </summary>
        /// <param name="entityName">The name of the entity to load </param>
        /// <param name="uniqueKeyPropertyName">The name of the property defining the unique key. </param>
        /// <param name="key">The unique key property value. </param>
        /// <param name="session">The originating session. </param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns> The loaded entity </returns>
        public async Task <object> LoadByUniqueKeyAsync(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ISessionFactoryImplementor factory   = session.Factory;
            IUniqueKeyLoadable         persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

            //TODO: implement caching?! proxies?!

            var keyType = GetIdentifierOrUniqueKeyType(factory)
                          // EntityUniqueKey was doing this on the type. I suspect this was needed only for its usage in Loader,
                          // which can work with entities as keys not yet instanciated and just represented by their identifiers.
                          // But since removing this call from EntityUniqueKey is done for a patch and that the code path here has
                          // no known bugs with this GetSemiResolvedType, moving its call here for avoiding altering this code
                          // path. See GH1645.
                          .GetSemiResolvedType(factory);
            EntityUniqueKey euk =
                new EntityUniqueKey(
                    entityName,
                    uniqueKeyPropertyName,
                    key,
                    keyType,
                    session.Factory);

            IPersistenceContext persistenceContext = session.PersistenceContext;

            try
            {
                object result = persistenceContext.GetEntity(euk);
                if (result == null)
                {
                    result = await(persister.LoadByUniqueKeyAsync(uniqueKeyPropertyName, key, session, cancellationToken)).ConfigureAwait(false);
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (OperationCanceledException) { throw; }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }
Exemple #33
0
        /// <summary>
        /// Load an instance by a unique key that is not the primary key.
        /// </summary>
        /// <param name="entityName">The name of the entity to load </param>
        /// <param name="uniqueKeyPropertyName">The name of the property defining the unique key. </param>
        /// <param name="key">The unique key property value. </param>
        /// <param name="session">The originating session. </param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns> The loaded entity </returns>
        public async Task <object> LoadByUniqueKeyAsync(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ISessionFactoryImplementor factory   = session.Factory;
            IUniqueKeyLoadable         persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

            //TODO: implement caching?! proxies?!

            var keyType = GetIdentifierOrUniqueKeyType(factory)
                          .GetSemiResolvedType(factory);
            EntityUniqueKey euk =
                new EntityUniqueKey(
                    entityName,
                    uniqueKeyPropertyName,
                    key,
                    keyType,
                    session.Factory);

            IPersistenceContext persistenceContext = session.PersistenceContext;

            try
            {
                object result = persistenceContext.GetEntity(euk);
                if (result == null)
                {
                    result = await(persister.LoadByUniqueKeyAsync(uniqueKeyPropertyName, key, session, cancellationToken)).ConfigureAwait(false);
                    if (result == null && !IsNullable)
                    {
                        factory.EntityNotFoundDelegate.HandleEntityNotFound(entityName, uniqueKeyPropertyName, key);
                    }
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (OperationCanceledException) { throw; }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }
		public override int GetHashCode(object x, ISessionFactoryImplementor factory)
		{
			IEntityPersister persister = factory.GetEntityPersister(associatedClass);
			if (!persister.HasIdentifierPropertyOrEmbeddedCompositeIdentifier)
			{
				return base.GetHashCode(x, factory);
			}

			object id;
			if (x is INHibernateProxy)
			{
				id = NHibernateProxyHelper.GetLazyInitializer((INHibernateProxy) x).Identifier;
			}
			else
			{
				id = persister.GetIdentifier(x);
			}
			return persister.IdentifierType.GetHashCode(id, factory);
		}
Exemple #35
0
        public static Type GetRootType(DetachedCriteria criteria, ISession session)
        {
            Type rootType = criteria.GetRootEntityTypeIfAvailable();

            if (rootType != null)
            {
                return(rootType);
            }

            ISessionFactoryImplementor factory   = (ISessionFactoryImplementor)session.SessionFactory;
            IEntityPersister           persister = factory.GetEntityPersister(criteria.EntityOrClassName);

            if (persister == null)
            {
                throw new InvalidOperationException("Could not find entity named: " + criteria.EntityOrClassName);
            }

            return(persister.GetMappedClass(EntityMode.Poco));
        }
		public override IType GetSemiResolvedType(ISessionFactoryImplementor factory)
		{
			return factory.GetEntityPersister(associatedEntityName).IdentifierType;
		}
		public override int GetHashCode(object x, EntityMode entityMode, ISessionFactoryImplementor factory)
		{
			IEntityPersister persister = factory.GetEntityPersister(associatedEntityName);
			if (!persister.CanExtractIdOutOfEntity)
			{
				return base.GetHashCode(x, entityMode);
			}

			object id;
			
			if (x.IsProxy())
			{
				INHibernateProxy proxy = x as INHibernateProxy; 
				id = proxy.HibernateLazyInitializer.Identifier;
			}
			else
			{
				id = persister.GetIdentifier(x, entityMode);
			}
			return persister.IdentifierType.GetHashCode(id, entityMode, factory);
		}
		public override string ToLoggableString(object value, ISessionFactoryImplementor factory)
		{
			if (value == null)
			{
				return "null";
			}

			IEntityPersister persister = factory.GetEntityPersister(associatedEntityName);
			StringBuilder result = new StringBuilder().Append(associatedEntityName);

			if (persister.HasIdentifierProperty)
			{
				EntityMode? entityMode = persister.GuessEntityMode(value);
				object id;
				if (!entityMode.HasValue)
				{
					if (isEmbeddedInXML)
						throw new InvalidCastException(value.GetType().FullName);

					id = value;
				}
				else
				{
					id = GetIdentifier(value, persister, entityMode.Value);
				}

				result.Append('#').Append(persister.IdentifierType.ToLoggableString(id, factory));
			}

			return result.ToString();
		}
Exemple #39
0
        public CustomLoader(
            ICustomQuery customQuery,
            ISessionFactoryImplementor factory)
            : base(factory)
        {
            this.sql = customQuery.SQL;
            this.querySpaces.AddAll(customQuery.QuerySpaces);
            this.namedParameterBindPoints = customQuery.NamedParameterBindPoints;

            IList entityPersisters = new ArrayList();
            IList entityOwners = new ArrayList();
            IList entityAliases = new ArrayList();

            IList collectionPersisters = new ArrayList();
            IList collectionOwners = new ArrayList();
            IList collectionAliases = new ArrayList();

            IList lockModes = new ArrayList();
            IList resultColumnProcessors = new ArrayList();
            IList nonScalarReturnList = new ArrayList();
            IList resultTypes = new ArrayList();
            IList specifiedAliases = new ArrayList();

            int returnableCounter = 0;
            bool hasScalars = false;

            foreach (IReturn rtn in customQuery.CustomQueryReturns)
            {
                if (rtn is ScalarReturn)
                {
                    ScalarReturn scalarRtn = (ScalarReturn) rtn;
                    resultTypes.Add(scalarRtn.Type);
                    specifiedAliases.Add(scalarRtn.ColumnAlias);
                    resultColumnProcessors.Add(
                        new ScalarResultColumnProcessor(
                            scalarRtn.ColumnAlias,
                            scalarRtn.Type
                            )
                        );
                    hasScalars = true;
                }
                else if (rtn is RootReturn)
                {
                    RootReturn rootRtn = (RootReturn) rtn;
                    IQueryable persister = (IQueryable) factory.GetEntityPersister(rootRtn.EntityName);
                    entityPersisters.Add(persister);
                    lockModes.Add(rootRtn.LockMode);
                    resultColumnProcessors.Add(new NonScalarResultColumnProcessor(returnableCounter++));
                    nonScalarReturnList.Add(rtn);
                    entityOwners.Add(-1);
                    resultTypes.Add(persister.Type);
                    specifiedAliases.Add(rootRtn.Alias);
                    entityAliases.Add(rootRtn.EntityAliases);
                    querySpaces.AddAll(persister.QuerySpaces);
                }
                else if (rtn is CollectionReturn)
                {
                    CollectionReturn collRtn = (CollectionReturn) rtn;
                    String role = collRtn.OwnerEntityName + "." + collRtn.OwnerProperty;
                    IQueryableCollection persister = (IQueryableCollection) factory.GetCollectionPersister(role);
                    collectionPersisters.Add(persister);
                    lockModes.Add(collRtn.LockMode);
                    resultColumnProcessors.Add(new NonScalarResultColumnProcessor(returnableCounter++));
                    nonScalarReturnList.Add(rtn);
                    collectionOwners.Add(-1);
                    resultTypes.Add(persister.Type);
                    specifiedAliases.Add(collRtn.Alias);
                    collectionAliases.Add(collRtn.CollectionAliases);
                    // determine if the collection elements are entities...
                    IType elementType = persister.ElementType;
                    if (elementType.IsEntityType)
                    {
                        IQueryable elementPersister = (IQueryable) ((EntityType) elementType).GetAssociatedJoinable(factory);
                        entityPersisters.Add(elementPersister);
                        entityOwners.Add(-1);
                        entityAliases.Add(collRtn.ElementEntityAliases);
                        querySpaces.AddAll(elementPersister.QuerySpaces);
                    }
                }
                else if (rtn is EntityFetchReturn)
                {
                    EntityFetchReturn fetchRtn = (EntityFetchReturn) rtn;
                    NonScalarReturn ownerDescriptor = fetchRtn.Owner;
                    int ownerIndex = nonScalarReturnList.IndexOf(ownerDescriptor);
                    entityOwners.Add(ownerIndex);
                    lockModes.Add(fetchRtn.LockMode);
                    IQueryable ownerPersister = DetermineAppropriateOwnerPersister(ownerDescriptor);
                    EntityType fetchedType = (EntityType) ownerPersister.GetPropertyType(fetchRtn.OwnerProperty);
                    string entityName = fetchedType.GetAssociatedEntityName(Factory);
                    IQueryable persister = (IQueryable) factory.GetEntityPersister(entityName);
                    entityPersisters.Add(persister);
                    nonScalarReturnList.Add(rtn);
                    specifiedAliases.Add(fetchRtn.Alias);
                    entityAliases.Add(fetchRtn.EntityAliases);
                    querySpaces.AddAll(persister.QuerySpaces);
                }
                else if (rtn is CollectionFetchReturn)
                {
                    CollectionFetchReturn fetchRtn = (CollectionFetchReturn) rtn;
                    NonScalarReturn ownerDescriptor = fetchRtn.Owner;
                    int ownerIndex = nonScalarReturnList.IndexOf(ownerDescriptor);
                    collectionOwners.Add(ownerIndex);
                    lockModes.Add(fetchRtn.LockMode);
                    IQueryable ownerPersister = DetermineAppropriateOwnerPersister(ownerDescriptor);
                    String role = ownerPersister.EntityName + '.' + fetchRtn.OwnerProperty;
                    IQueryableCollection persister = (IQueryableCollection) factory.GetCollectionPersister(role);
                    collectionPersisters.Add(persister);
                    nonScalarReturnList.Add(rtn);
                    specifiedAliases.Add(fetchRtn.Alias);
                    collectionAliases.Add(fetchRtn.CollectionAliases);
                    // determine if the collection elements are entities...
                    IType elementType = persister.ElementType;
                    if (elementType.IsEntityType)
                    {
                        IQueryable elementPersister = (IQueryable) ((EntityType) elementType).GetAssociatedJoinable(factory);
                        entityPersisters.Add(elementPersister);
                        entityOwners.Add(ownerIndex);
                        entityAliases.Add(fetchRtn.ElementEntityAliases);
                        querySpaces.AddAll(elementPersister.QuerySpaces);
                    }
                }
                else
                {
                    throw new HibernateException("unexpected custom query return type : " + rtn.GetType().FullName);
                }
            }

            this.entityPersisters = new IQueryable[entityPersisters.Count];
            for (int i = 0; i < entityPersisters.Count; i++)
            {
                this.entityPersisters[i] = (IQueryable) entityPersisters[i];
            }
            this.entityOwners = ArrayHelper.ToIntArray(entityOwners);
            this.entityAliases = new IEntityAliases[entityAliases.Count];
            for (int i = 0; i < entityAliases.Count; i++)
            {
                this.entityAliases[i] = (IEntityAliases) entityAliases[i];
            }

            this.collectionPersisters = new IQueryableCollection[collectionPersisters.Count];
            for (int i = 0; i < collectionPersisters.Count; i++)
            {
                this.collectionPersisters[i] = (IQueryableCollection) collectionPersisters[i];
            }
            this.collectionOwners = ArrayHelper.ToIntArray(collectionOwners);
            this.collectionAliases = new ICollectionAliases[collectionAliases.Count];
            for (int i = 0; i < collectionAliases.Count; i++)
            {
                this.collectionAliases[i] = (ICollectionAliases) collectionAliases[i];
            }

            this.lockModes = new LockMode[lockModes.Count];
            for (int i = 0; i < lockModes.Count; i++)
            {
                this.lockModes[i] = (LockMode) lockModes[i];
            }

            this.resultTypes = ArrayHelper.ToTypeArray(resultTypes);
            this.transformerAliases = ArrayHelper.ToStringArray(specifiedAliases);

            this.rowProcessor = new ResultRowProcessor(
                hasScalars,
                (ResultColumnProcessor[]) ArrayHelper.ToArray(resultColumnProcessors, typeof(ResultColumnProcessor))
                );
        }
		public AbstractCollectionPersister(Mapping.Collection collection, ICacheConcurrencyStrategy cache,
		                                   ISessionFactoryImplementor factory)
		{
			this.factory = factory;
			dialect = factory.Dialect;
			this.cache = cache;
			//sqlExceptionConverter = factory.SQLExceptionConverter;
			collectionType = collection.CollectionType;
			role = collection.Role;
			ownerClass = collection.OwnerClass;
			ownerPersister = factory.GetEntityPersister(ownerClass);
			queryLoaderName = collection.LoaderName;
			Alias alias = new Alias("__");

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

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

			hasOrphanDelete = collection.OrphanDelete;

			batchSize = collection.BatchSize;
			isVersioned = collection.IsOptimisticLocked;

			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.GetAlias(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;
			subselectLoadable = collection.IsSubselectLoadable;

			IValue element = collection.Element;
			int elementSpan = element.ColumnSpan;
			Table table = collection.CollectionTable;
			fetchMode = element.FetchMode;
			elementType = element.Type;

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

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

			qualifiedTableName = table.GetQualifiedName(dialect, factory.DefaultSchema);
			elementColumnAliases = new string[elementSpan];
			elementColumnNames = new string[elementSpan];
			elementFormulaTemplates = new string[elementSpan];
			elementFormulas = new string[elementSpan];
			elementColumnIsSettable = new bool[elementSpan];
			elementColumnIsInPrimaryKey = new bool[elementSpan];
			int j = 0;
			foreach (ISelectable selectable in element.ColumnCollection)
			{
				elementColumnAliases[j] = selectable.GetAlias(dialect);
				if (selectable.IsFormula)
				{
					Formula form = (Formula) selectable;
					elementFormulaTemplates[j] = form.GetTemplate(dialect, factory.SQLFunctionRegistry);
					elementFormulas[j] = form.FormulaString;
				}
				else
				{
					Column col = (Column) selectable;
					elementColumnNames[j] = col.GetQuotedName(dialect);
					elementColumnIsSettable[j] = true;
					elementColumnIsInPrimaryKey[j] = !col.IsNullable;
				}
				j++;
			}

			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.GetAlias(dialect);
					indexColumnNames[i] = indexCol.GetQuotedName(dialect);
					i++;
				}
				indexColumnAliases = alias.ToAliasStrings(indexAliases, dialect);
				CheckColumnDuplication(distinctColumns, indexedCollection.Index.ColumnCollection);
			}
			else
			{
				indexType = null;
				indexColumnNames = null;
				indexColumnAliases = null;
			}

			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);
				identifierColumnAlias = alias.ToAliasString(col.GetAlias(dialect), dialect);
				identifierGenerator = idColl.Identifier.CreateIdentifierGenerator(dialect);
				CheckColumnDuplication(distinctColumns, idColl.Identifier.ColumnCollection);
			}
			else
			{
				identifierType = null;
				identifierColumnName = null;
				identifierColumnAlias = null;
				identifierGenerator = null;
			}

			sqlInsertRowString = GenerateInsertRowString();
			if (collection.CustomSQLInsert == null)
			{
				insertCallable = false;
				insertCheckStyle = ExecuteUpdateResultCheckStyle.Count;
			}
			else
			{
				sqlInsertRowString = new SqlCommandInfo(collection.CustomSQLInsert, sqlInsertRowString.ParameterTypes);
				insertCallable = collection.IsCustomInsertCallable;
				insertCheckStyle = collection.CustomSQLInsertCheckStyle == null
				                   	? ExecuteUpdateResultCheckStyle.DetermineDefault(collection.CustomSQLInsert, insertCallable)
				                   	: collection.CustomSQLInsertCheckStyle;
			}

			sqlUpdateRowString = GenerateUpdateRowString();
			if (collection.CustomSQLUpdate == null)
			{
				updateCallable = false;
				updateCheckStyle = ExecuteUpdateResultCheckStyle.Count;
			}
			else
			{
				sqlUpdateRowString = new SqlCommandInfo(collection.CustomSQLUpdate, sqlUpdateRowString.ParameterTypes);
				updateCallable = collection.IsCustomUpdateCallable;
				updateCheckStyle = collection.CustomSQLUpdateCheckStyle == null
				                   	? ExecuteUpdateResultCheckStyle.DetermineDefault(collection.CustomSQLUpdate, updateCallable)
				                   	: collection.CustomSQLUpdateCheckStyle;
			}

			sqlDeleteRowString = GenerateDeleteRowString();
			if (collection.CustomSQLDelete == null)
			{
				deleteCallable = false;
				deleteCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}
			else
			{
				sqlDeleteRowString = new SqlCommandInfo(collection.CustomSQLDelete, sqlDeleteRowString.ParameterTypes);
				deleteCallable = collection.IsCustomDeleteCallable;
				deleteCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}

			sqlDeleteString = GenerateDeleteString();
			if (collection.CustomSQLDeleteAll == null)
			{
				deleteAllCallable = false;
				deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}
			else
			{
				sqlDeleteString = new SqlCommandInfo(collection.CustomSQLDeleteAll, sqlDeleteString.ParameterTypes);
				deleteAllCallable = collection.IsCustomDeleteAllCallable;
				deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}

			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;
			}

			if (elementType.IsComponentType)
			{
				elementPropertyMapping = new CompositeElementPropertyMapping(
					elementColumnNames, elementFormulaTemplates,
					(IAbstractComponentType) elementType, factory);
			}
			else if (!elementType.IsEntityType)
			{
				elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
			}
			else
			{
				IEntityPersister persister = factory.GetEntityPersister(((EntityType) elementType).AssociatedClass);
				// Not all classpersisters implement IPropertyMapping!
				if (persister is IPropertyMapping)
				{
					elementPropertyMapping = (IPropertyMapping) persister;
				}
				else
				{
					elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
				}
			}

			// Handle any filters applied to this collection
			filterHelper = new FilterHelper(collection.FilterMap, dialect, factory.SQLFunctionRegistry);

			// Handle any filters applied to this collection for many-to-many
			manyToManyFilterHelper = new FilterHelper(collection.ManyToManyFilterMap, dialect, factory.SQLFunctionRegistry);
			manyToManyWhereString = StringHelper.IsNotEmpty(collection.ManyToManyWhere) ?
			                        "( " + collection.ManyToManyWhere + " )" :
			                        null;
			manyToManyWhereTemplate = manyToManyWhereString == null
			                          	?
			                          null
			                          	:
			                          Template.RenderWhereStringTemplate(manyToManyWhereString, factory.Dialect,
			                                                             factory.SQLFunctionRegistry);
				// , factory.getSqlFunctionRegistry() );
			manyToManyOrderByString = collection.ManyToManyOrdering;
			manyToManyOrderByTemplate = manyToManyOrderByString == null
			                            	? null
			                            	: Template.RenderOrderByStringTemplate(manyToManyOrderByString, factory.Dialect,
			                            	                                       factory.SQLFunctionRegistry);
				// , factory.getSqlFunctionRegistry() );

			InitCollectionPropertyMap();
		}
		public override string ToLoggableString(object value, ISessionFactoryImplementor factory)
		{
			IEntityPersister persister = factory.GetEntityPersister(associatedClass);
			if (value == null)
			{
				return "null";
			}
			StringBuilder result = new StringBuilder();
			result.Append(StringHelper.Unqualify(NHibernateProxyHelper.GetClass(value).FullName));
			if (persister.HasIdentifierProperty)
			{
				result.Append('#')
					.Append(persister.IdentifierType.ToLoggableString(NHibernateProxyHelper.GetIdentifier(value, persister), factory));
			}

			return result.ToString();
		}
        public IEntityPersister GetSubclassEntityPersister(object instance, ISessionFactoryImplementor factory,
																											EntityMode entityMode)
        {
            if (!HasSubclasses)
            {
                return this;
            }
            else
            {
                // TODO : really need a way to do something like :
                //      getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)
                System.Type clazz = instance.GetType();
                if (clazz == GetMappedClass(entityMode))
                {
                    return this;
                }
                else
                {
                    string subclassEntityName = GetSubclassEntityName(clazz);
                    if (subclassEntityName == null)
                    {
                        throw new HibernateException("instance not of expected entity type: " + clazz.FullName + " is not a: "
                                                                                 + EntityName);
                    }
                    else
                    {
                        return factory.GetEntityPersister(subclassEntityName);
                    }
                }
            }
        }
		/// <summary> Retrieves the {@link Joinable} defining the associated entity. </summary>
		/// <param name="factory">The session factory. </param>
		/// <returns> The associated joinable </returns>
		public IJoinable GetAssociatedJoinable(ISessionFactoryImplementor factory)
		{
			return (IJoinable)factory.GetEntityPersister(associatedEntityName);
		}
		public IEntityPersister GetSubclassEntityPersister(object instance, ISessionFactoryImplementor factory,
																											EntityMode entityMode)
		{
			if (!HasSubclasses)
			{
				return this;
			}
			// TODO : really need a way to do something like :
			//      getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)
			var clazz = instance.GetType();
			if (clazz == GetMappedClass(entityMode))
			{
				return this;
			}
			var subclassEntityName = GetSubclassEntityName(clazz);
			if (subclassEntityName == null || EntityName.Equals(subclassEntityName))
			{
				return this;
			}
			return factory.GetEntityPersister(subclassEntityName);
		}
		protected virtual IEntityPersister GetEntityPersister(ISessionFactoryImplementor factory, string entityName)
		{
			// Check for an exact match.
			IEntityPersister persister = factory.TryGetEntityPersister(entityName);
			if (persister != null)
			{
				return persister;
			}

			// Couldn't find persister through exact name, try finding a single implementing class.
			string[] implementors = factory.GetImplementors(entityName);
			if (implementors.Length > 1)
			{
				var messageBuilder = new StringBuilder(512);
				messageBuilder.AppendLine(string.Format("Ambiguous persister for {0} implemented by more than one hierarchy: ",
				                                        entityName));
				Array.ForEach(implementors, s=> messageBuilder.AppendLine(s));

				throw new HibernateException(messageBuilder.ToString());
			}
			if (implementors.Length == 0)
			{
				return null;
			}
			return factory.GetEntityPersister(implementors[0]);
		}
		public AbstractCollectionPersister(Mapping.Collection collection, ICacheConcurrencyStrategy cache, Configuration cfg,
		                                   ISessionFactoryImplementor factory)
		{
			this.factory = factory;
			this.cache = cache;
			if (factory.Settings.IsStructuredCacheEntriesEnabled)
			{
				cacheEntryStructure = collection.IsMap
				                      	? (ICacheEntryStructure) new StructuredMapCacheEntry()
				                      	: (ICacheEntryStructure) new StructuredCollectionCacheEntry();
			}
			else
			{
				cacheEntryStructure = new UnstructuredCacheEntry();
			}

			dialect = factory.Dialect;
			sqlExceptionConverter = factory.SQLExceptionConverter;
			collectionType = collection.CollectionType;
			role = collection.Role;
			entityName = collection.OwnerEntityName;
			ownerPersister = factory.GetEntityPersister(entityName);
			queryLoaderName = collection.LoaderName;
			nodeName = collection.NodeName;
			isMutable = collection.IsMutable;

			Table table = collection.CollectionTable;
			fetchMode = collection.Element.FetchMode;
			elementType = collection.Element.Type;
			isPrimitiveArray = collection.IsPrimitiveArray;
			isArray = collection.IsArray;
			subselectLoadable = collection.IsSubselectLoadable;
			qualifiedTableName = table.GetQualifiedName(dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName);

			int spacesSize = 1 + collection.SynchronizedTables.Count;
			spaces = new string[spacesSize];
			int ispa = 0;
			spaces[ispa++] = qualifiedTableName;
			foreach (string s in collection.SynchronizedTables)
			{
				spaces[ispa++] = s;
			}

			sqlOrderByString = collection.OrderBy;
			hasOrder = sqlOrderByString != null;
			sqlOrderByStringTemplate = hasOrder
			                           	? Template.RenderOrderByStringTemplate(sqlOrderByString, dialect,
			                           	                                       factory.SQLFunctionRegistry)
			                           	: null;
			sqlWhereString = !string.IsNullOrEmpty(collection.Where) ? '(' + collection.Where + ')' : null;
			hasWhere = sqlWhereString != null;
			sqlWhereStringTemplate = hasWhere
			                         	? Template.RenderWhereStringTemplate(sqlWhereString, dialect, factory.SQLFunctionRegistry)
			                         	: null;
			hasOrphanDelete = collection.HasOrphanDelete;
			int batch = collection.BatchSize;
			if (batch == -1)
			{
				batch = factory.Settings.DefaultBatchFetchSize;
			}
			batchSize = batch;

			isVersioned = collection.IsOptimisticLocked;

			keyType = collection.Key.Type;
			int keySpan = collection.Key.ColumnSpan;
			keyColumnNames = new string[keySpan];
			keyColumnAliases = new string[keySpan];
			int k = 0;
			foreach (Column col in collection.Key.ColumnIterator)
			{
				keyColumnNames[k] = col.GetQuotedName(dialect);
				keyColumnAliases[k] = col.GetAlias(dialect);
				k++;
			}
			ISet distinctColumns = new HashedSet();
			CheckColumnDuplication(distinctColumns, collection.Key.ColumnIterator);

			#region Element

			IValue element = collection.Element;
			if (!collection.IsOneToMany)
			{
				CheckColumnDuplication(distinctColumns, element.ColumnIterator);
			}

			string elemNode = collection.ElementNodeName;
			if (elementType.IsEntityType)
			{
				string _entityName = ((EntityType) elementType).GetAssociatedEntityName();
				elementPersister = factory.GetEntityPersister(_entityName);
				if (elemNode == null)
				{
					elemNode = cfg.GetClassMapping(_entityName).NodeName;
				}
				// NativeSQL: collect element column and auto-aliases
			}
			else
			{
				elementPersister = null;
			}
			elementNodeName = elemNode;

			int elementSpan = element.ColumnSpan;
			elementColumnAliases = new string[elementSpan];
			elementColumnNames = new string[elementSpan];
			elementFormulaTemplates = new string[elementSpan];
			elementFormulas = new string[elementSpan];
			elementColumnIsSettable = new bool[elementSpan];
			elementColumnIsInPrimaryKey = new bool[elementSpan];
			bool isPureFormula = true;
			bool hasNotNullableColumns = false;
			int j = 0;
			foreach (ISelectable selectable in element.ColumnIterator)
			{
				elementColumnAliases[j] = selectable.GetAlias(dialect);
				if (selectable.IsFormula)
				{
					Formula form = (Formula) selectable;
					elementFormulaTemplates[j] = form.GetTemplate(dialect, factory.SQLFunctionRegistry);
					elementFormulas[j] = form.FormulaString;
				}
				else
				{
					Column col = (Column) selectable;
					elementColumnNames[j] = col.GetQuotedName(dialect);
					elementColumnIsSettable[j] = true;
					elementColumnIsInPrimaryKey[j] = !col.IsNullable;
					if (!col.IsNullable)
					{
						hasNotNullableColumns = true;
					}

					isPureFormula = false;
				}
				j++;
			}
			elementIsPureFormula = isPureFormula;

			//workaround, for backward compatibility of sets with no
			//not-null columns, assume all columns are used in the
			//row locator SQL
			if (!hasNotNullableColumns)
			{
				ArrayHelper.Fill(elementColumnIsInPrimaryKey, true);
			}

			#endregion

			#region INDEX AND ROW SELECT

			hasIndex = collection.IsIndexed;
			if (hasIndex)
			{
				// NativeSQL: collect index column and auto-aliases
				IndexedCollection indexedCollection = (IndexedCollection) collection;
				indexType = indexedCollection.Index.Type;
				int indexSpan = indexedCollection.Index.ColumnSpan;
				indexColumnNames = new string[indexSpan];
				indexFormulaTemplates = new string[indexSpan];
				indexFormulas = new string[indexSpan];
				indexColumnIsSettable = new bool[indexSpan];
				indexColumnAliases = new string[indexSpan];
				bool hasFormula = false;
				int i = 0;
				foreach (ISelectable selectable in indexedCollection.Index.ColumnIterator)
				{
					indexColumnAliases[i] = selectable.GetAlias(dialect);
					if (selectable.IsFormula)
					{
						Formula indexForm = (Formula) selectable;
						indexFormulaTemplates[i] = indexForm.GetTemplate(dialect, factory.SQLFunctionRegistry);
						indexFormulas[i] = indexForm.FormulaString;
						hasFormula = true;
					}
					else
					{
						Column indexCol = (Column) selectable;
						indexColumnNames[i] = indexCol.GetQuotedName(dialect);
						indexColumnIsSettable[i] = true;
					}
					i++;
				}
				indexContainsFormula = hasFormula;
				baseIndex = indexedCollection.IsList ? ((List) indexedCollection).BaseIndex : 0;

				indexNodeName = indexedCollection.IndexNodeName;
				CheckColumnDuplication(distinctColumns, indexedCollection.Index.ColumnIterator);
			}
			else
			{
				indexContainsFormula = false;
				indexColumnIsSettable = null;
				indexFormulaTemplates = null;
				indexFormulas = null;
				indexType = null;
				indexColumnNames = null;
				indexColumnAliases = null;
				baseIndex = 0;
				indexNodeName = null;
			}

			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.ColumnIterator)
				{
					col = column;
					break;
				}

				identifierColumnName = col.GetQuotedName(dialect);
				identifierColumnAlias = col.GetAlias(dialect);
				identifierGenerator =
					idColl.Identifier.CreateIdentifierGenerator(factory.Dialect, factory.Settings.DefaultCatalogName,
					                                            factory.Settings.DefaultSchemaName, null);
				// NH see : identityDelegate declaration
				IPostInsertIdentifierGenerator pig = (identifierGenerator as IPostInsertIdentifierGenerator);
				if (pig != null)
				{
					identityDelegate = pig.GetInsertGeneratedIdentifierDelegate(this, Factory, UseGetGeneratedKeys());
				}
				else
				{
					identityDelegate = null;
				}

				CheckColumnDuplication(distinctColumns, idColl.Identifier.ColumnIterator);
			}
			else
			{
				identifierType = null;
				identifierColumnName = null;
				identifierColumnAlias = null;
				identifierGenerator = null;
				identityDelegate = null;
			}

			#endregion

			#region GENERATE THE SQL

			// NH Different behavior : for the Insert SQL we are managing isPostInsertIdentifier (not supported in H3.2.5) 
			if (collection.CustomSQLInsert == null)
			{
				if (!IsIdentifierAssignedByInsert)
				{
					sqlInsertRowString = GenerateInsertRowString();
				}
				else
				{
					sqlInsertRowString = GenerateIdentityInsertRowString();
				}
				insertCallable = false;
				insertCheckStyle = ExecuteUpdateResultCheckStyle.Count;
			}
			else
			{
				SqlType[] parmsTypes = GenerateInsertRowString().ParameterTypes;
				sqlInsertRowString = new SqlCommandInfo(collection.CustomSQLInsert, parmsTypes);
				insertCallable = collection.IsCustomInsertCallable;
				insertCheckStyle = collection.CustomSQLInsertCheckStyle
				                   ?? ExecuteUpdateResultCheckStyle.DetermineDefault(collection.CustomSQLInsert, insertCallable);
			}

			sqlUpdateRowString = GenerateUpdateRowString();
			if (collection.CustomSQLUpdate == null)
			{
				updateCallable = false;
				updateCheckStyle = ExecuteUpdateResultCheckStyle.Count;
			}
			else
			{
				sqlUpdateRowString = new SqlCommandInfo(collection.CustomSQLUpdate, sqlUpdateRowString.ParameterTypes);
				updateCallable = collection.IsCustomUpdateCallable;
				updateCheckStyle = collection.CustomSQLUpdateCheckStyle
				                   ?? ExecuteUpdateResultCheckStyle.DetermineDefault(collection.CustomSQLUpdate, updateCallable);
			}

			sqlDeleteRowString = GenerateDeleteRowString();
			if (collection.CustomSQLDelete == null)
			{
				deleteCallable = false;
				deleteCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}
			else
			{
				sqlDeleteRowString = new SqlCommandInfo(collection.CustomSQLDelete, sqlDeleteRowString.ParameterTypes);
				deleteCallable = collection.IsCustomDeleteCallable;
				deleteCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}

			sqlDeleteString = GenerateDeleteString();
			if (collection.CustomSQLDeleteAll == null)
			{
				deleteAllCallable = false;
				deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}
			else
			{
				sqlDeleteString = new SqlCommandInfo(collection.CustomSQLDeleteAll, sqlDeleteString.ParameterTypes);
				deleteAllCallable = collection.IsCustomDeleteAllCallable;
				deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.None;
			}

		    isCollectionIntegerIndex = collection.IsIndexed && !collection.IsMap;
			sqlDetectRowByIndexString = GenerateDetectRowByIndexString();
			sqlDetectRowByElementString = GenerateDetectRowByElementString();
			sqlSelectRowByIndexString = GenerateSelectRowByIndexString();

			LogStaticSQL();

			#endregion

			isLazy = collection.IsLazy;
			isExtraLazy = collection.ExtraLazy;
			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;
			}

			if (elementType.IsComponentType)
			{
				elementPropertyMapping =
					new CompositeElementPropertyMapping(elementColumnNames, elementFormulaTemplates,
					                                    (IAbstractComponentType) elementType, factory);
			}
			else if (!elementType.IsEntityType)
			{
				elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
			}
			else
			{
				elementPropertyMapping = elementPersister as IPropertyMapping;
				if (elementPropertyMapping == null)
				{
					elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
				}
			}

			// Handle any filters applied to this collection
			filterHelper = new FilterHelper(collection.FilterMap, dialect, factory.SQLFunctionRegistry);

			// Handle any filters applied to this collection for many-to-many
			manyToManyFilterHelper = new FilterHelper(collection.ManyToManyFilterMap, dialect, factory.SQLFunctionRegistry);
			manyToManyWhereString = !string.IsNullOrEmpty(collection.ManyToManyWhere)
			                        	? "( " + collection.ManyToManyWhere + " )"
			                        	: null;
			manyToManyWhereTemplate = manyToManyWhereString == null
			                          	? null
			                          	: Template.RenderWhereStringTemplate(manyToManyWhereString, factory.Dialect,
			                          	                                     factory.SQLFunctionRegistry);
			manyToManyOrderByString = collection.ManyToManyOrdering;
			manyToManyOrderByTemplate = manyToManyOrderByString == null
			                            	? null
			                            	: Template.RenderOrderByStringTemplate(manyToManyOrderByString, factory.Dialect,
			                            	                                       factory.SQLFunctionRegistry);
			InitCollectionPropertyMap();
		}
		public CustomLoader(ICustomQuery customQuery, ISessionFactoryImplementor factory) : base(factory)
		{
			sql = customQuery.SQL;
			querySpaces.AddAll(customQuery.QuerySpaces);
			namedParameterBindPoints = customQuery.NamedParameterBindPoints;

			List<IQueryable> entitypersisters = new List<IQueryable>();
			List<int> entityowners = new List<int>();
			List<IEntityAliases> entityaliases = new List<IEntityAliases>();

			List<IQueryableCollection> collectionpersisters = new List<IQueryableCollection>();
			List<int> collectionowners = new List<int>();
			List<ICollectionAliases> collectionaliases = new List<ICollectionAliases>();

			List<LockMode> lockmodes = new List<LockMode>();
			List<IResultColumnProcessor> resultColumnProcessors = new List<IResultColumnProcessor>();
			List<IReturn> nonScalarReturnList = new List<IReturn>();
			List<IType> resulttypes = new List<IType>();
			List<string> specifiedAliases = new List<string>();

			int returnableCounter = 0;
			bool hasScalars = false;

			foreach (IReturn rtn in customQuery.CustomQueryReturns)
			{
				if (rtn is ScalarReturn)
				{
					ScalarReturn scalarRtn = (ScalarReturn) rtn;
					resulttypes.Add(scalarRtn.Type);
					specifiedAliases.Add(scalarRtn.ColumnAlias);
					resultColumnProcessors.Add(new ScalarResultColumnProcessor(scalarRtn.ColumnAlias, scalarRtn.Type));
					hasScalars = true;
				}
				else if (rtn is RootReturn)
				{
					RootReturn rootRtn = (RootReturn) rtn;
					IQueryable persister = (IQueryable) factory.GetEntityPersister(rootRtn.EntityName);
					entitypersisters.Add(persister);
					lockmodes.Add(rootRtn.LockMode);
					resultColumnProcessors.Add(new NonScalarResultColumnProcessor(returnableCounter++));
					nonScalarReturnList.Add(rtn);
					entityowners.Add(-1);
					resulttypes.Add(persister.Type);
					specifiedAliases.Add(rootRtn.Alias);
					entityaliases.Add(rootRtn.EntityAliases);
					querySpaces.AddAll(persister.QuerySpaces);
				}
				else if (rtn is CollectionReturn)
				{
					CollectionReturn collRtn = (CollectionReturn) rtn;
					string role = collRtn.OwnerEntityName + "." + collRtn.OwnerProperty;
					IQueryableCollection persister = (IQueryableCollection) factory.GetCollectionPersister(role);
					collectionpersisters.Add(persister);
					lockmodes.Add(collRtn.LockMode);
					resultColumnProcessors.Add(new NonScalarResultColumnProcessor(returnableCounter++));
					nonScalarReturnList.Add(rtn);
					collectionowners.Add(-1);
					resulttypes.Add(persister.Type);
					specifiedAliases.Add(collRtn.Alias);
					collectionaliases.Add(collRtn.CollectionAliases);
					// determine if the collection elements are entities...
					IType elementType = persister.ElementType;
					if (elementType.IsEntityType)
					{
						IQueryable elementPersister = (IQueryable) ((EntityType) elementType).GetAssociatedJoinable(factory);
						entitypersisters.Add(elementPersister);
						entityowners.Add(-1);
						entityaliases.Add(collRtn.ElementEntityAliases);
						querySpaces.AddAll(elementPersister.QuerySpaces);
					}
				}
				else if (rtn is EntityFetchReturn)
				{
					EntityFetchReturn fetchRtn = (EntityFetchReturn) rtn;
					NonScalarReturn ownerDescriptor = fetchRtn.Owner;
					int ownerIndex = nonScalarReturnList.IndexOf(ownerDescriptor);
					entityowners.Add(ownerIndex);
					lockmodes.Add(fetchRtn.LockMode);
					IQueryable ownerPersister = DetermineAppropriateOwnerPersister(ownerDescriptor);
					EntityType fetchedType = (EntityType) ownerPersister.GetPropertyType(fetchRtn.OwnerProperty);
					string entityName = fetchedType.GetAssociatedEntityName(Factory);
					IQueryable persister = (IQueryable) factory.GetEntityPersister(entityName);
					entitypersisters.Add(persister);
					nonScalarReturnList.Add(rtn);
					specifiedAliases.Add(fetchRtn.Alias);
					entityaliases.Add(fetchRtn.EntityAliases);
					querySpaces.AddAll(persister.QuerySpaces);
				}
				else if (rtn is CollectionFetchReturn)
				{
					CollectionFetchReturn fetchRtn = (CollectionFetchReturn) rtn;
					NonScalarReturn ownerDescriptor = fetchRtn.Owner;
					int ownerIndex = nonScalarReturnList.IndexOf(ownerDescriptor);
					collectionowners.Add(ownerIndex);
					lockmodes.Add(fetchRtn.LockMode);
					IQueryable ownerPersister = DetermineAppropriateOwnerPersister(ownerDescriptor);
					string role = ownerPersister.EntityName + '.' + fetchRtn.OwnerProperty;
					IQueryableCollection persister = (IQueryableCollection) factory.GetCollectionPersister(role);
					collectionpersisters.Add(persister);
					nonScalarReturnList.Add(rtn);
					specifiedAliases.Add(fetchRtn.Alias);
					collectionaliases.Add(fetchRtn.CollectionAliases);
					// determine if the collection elements are entities...
					IType elementType = persister.ElementType;
					if (elementType.IsEntityType)
					{
						IQueryable elementPersister = (IQueryable) ((EntityType) elementType).GetAssociatedJoinable(factory);
						entitypersisters.Add(elementPersister);
						entityowners.Add(ownerIndex);
						entityaliases.Add(fetchRtn.ElementEntityAliases);
						querySpaces.AddAll(elementPersister.QuerySpaces);
					}
				}
				else
				{
					throw new HibernateException("unexpected custom query return type : " + rtn.GetType().FullName);
				}
			}

			entityPersisters = entitypersisters.ToArray();
			entityOwners = entityowners.ToArray();
			entityAliases = entityaliases.ToArray();
			collectionPersisters = collectionpersisters.ToArray();
			collectionOwners = collectionowners.ToArray();
			collectionAliases = collectionaliases.ToArray();
			lockModes = lockmodes.ToArray();
			resultTypes = resulttypes.ToArray();
			transformerAliases = specifiedAliases.ToArray();
			rowProcessor = new ResultRowProcessor(hasScalars, resultColumnProcessors.ToArray());
		}