private static string DetermineNameOfPropertyToUse(IEntityPersister persister, string supplied)
        {
            if (supplied != null)
            {
                return(supplied);
            }
            int[] naturalIdPropertyIndices = persister.NaturalIdentifierProperties;
            if (naturalIdPropertyIndices == null)
            {
                throw new IdentifierGenerationException("no natural-id property defined; need to specify [key] in "
                                                        + "generator parameters");
            }
            if (naturalIdPropertyIndices.Length > 1)
            {
                throw new IdentifierGenerationException("select generator does not currently support composite "
                                                        + "natural-id properties; need to specify [key] in generator parameters");
            }
            ValueInclusion inclusion = persister.PropertyInsertGenerationInclusions[naturalIdPropertyIndices[0]];

            if (inclusion != ValueInclusion.None)
            {
                throw new IdentifierGenerationException("natural-id also defined as insert-generated; need to specify [key] "
                                                        + "in generator parameters");
            }
            return(persister.PropertyNames[naturalIdPropertyIndices[0]]);
        }
			public NoneInclusionChecker(ValueInclusion[] inclusions)
			{
				this.inclusions = inclusions;
			}
		private void ProcessGeneratedProperties(object id, object entity, object[] state,
				ISessionImplementor session, SqlString selectionSQL, ValueInclusion[] includeds)
		{
			session.Batcher.ExecuteBatch(); //force immediate execution of the insert

			using (new SessionIdLoggingContext(session.SessionId)) 
			try
			{
				IDbCommand cmd =
					session.Batcher.PrepareQueryCommand(CommandType.Text, selectionSQL, IdentifierType.SqlTypes(Factory));
				IDataReader rs = null;
				try
				{
					IdentifierType.NullSafeSet(cmd, id, 0, session);
					rs = session.Batcher.ExecuteReader(cmd);
					if (!rs.Read())
					{
						throw new HibernateException("Unable to locate row for retrieval of generated properties: "
																				 + MessageHelper.InfoString(this, id, Factory));
					}
					for (int i = 0; i < PropertySpan; i++)
					{
						if (includeds[i] != ValueInclusion.None)
						{
							object hydratedState = PropertyTypes[i].Hydrate(rs, GetPropertyAliases(string.Empty, i), session, entity);
							state[i] = PropertyTypes[i].ResolveIdentifier(hydratedState, session, entity);
							SetPropertyValue(entity, i, state[i], session.EntityMode);
						}
					}
				}
				finally
				{
					session.Batcher.CloseCommand(cmd, rs);
				}
			}
			catch (DbException sqle)
			{
				var exceptionContext = new AdoExceptionContextInfo
				                       	{
				                       		SqlException = sqle,
				                       		Message = "unable to select generated column values",
				                       		Sql = selectionSQL.ToString(),
				                       		EntityName = EntityName,
				                       		EntityId = id
				                       	};
				throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, exceptionContext);
			}
		}
		protected string ConcretePropertySelectFragment(string alias, ValueInclusion[] inclusions)
		{
			return ConcretePropertySelectFragment(alias, new NoneInclusionChecker(inclusions));
		}
		private SqlString GenerateGeneratedValuesSelectString(ValueInclusion[] inclusions)
		{
			SqlSelectBuilder select = new SqlSelectBuilder(Factory);

			if (Factory.Settings.IsCommentsEnabled)
			{
				select.SetComment("get generated state " + EntityName);
			}

			string[] aliasedIdColumns = StringHelper.Qualify(RootAlias, IdentifierColumnNames);

			// Here we render the select column list based on the properties defined as being generated.
			// For partial component generation, we currently just re-select the whole component
			// rather than trying to handle the individual generated portions.
			string selectClause = ConcretePropertySelectFragment(RootAlias, inclusions);
			selectClause = selectClause.Substring(2);

			string fromClause = FromTableFragment(RootAlias) + FromJoinFragment(RootAlias, true, false);

			SqlString whereClause = new SqlStringBuilder()
				.Add(StringHelper.Join(new SqlString("=", Parameter.Placeholder, " and "), aliasedIdColumns))
				.Add("=").AddParameter()
				.Add(WhereJoinFragment(RootAlias, true, false))
				.ToSqlString();

			return select.SetSelectClause(selectClause)
				.SetFromClause(fromClause)
				.SetOuterJoins(SqlString.Empty, SqlString.Empty)
				.SetWhereClause(whereClause)
				.ToSqlString();
		}
		private void ProcessGeneratedProperties(
				object id,
				object entity,
				object[] state,
				ISessionImplementor session,
				SqlString selectionSQL,
				ValueInclusion[] includeds)
		{
			session.Batcher.ExecuteBatch(); //force immediate execution of the insert

			try
			{
				IDbCommand cmd =
					session.Batcher.PrepareQueryCommand(CommandType.Text, selectionSQL, IdentifierType.SqlTypes(Factory));
				IDataReader rs = null;
				try
				{
					IdentifierType.NullSafeSet(cmd, id, 0, session);
					rs = session.Batcher.ExecuteReader(cmd);
					if (!rs.Read())
					{
						throw new HibernateException(
							"Unable to locate row for retrieval of generated properties: " +
							MessageHelper.InfoString(this, id, Factory)
							);
					}
					for (int i = 0; i < entityMetamodel.PropertySpan; i++)
					{
						if (includeds[i] != ValueInclusion.None)
						{
							object hydratedState = PropertyTypes[i].Hydrate(rs, GetPropertyAliases("", i), session, entity);
							state[i] = PropertyTypes[i].ResolveIdentifier(hydratedState, session, entity);
							SetPropertyValue(entity, i, state[i]);
						}
					}
				}
				finally
				{
					session.Batcher.CloseCommand(cmd, rs);
				}
			}
			catch (HibernateException)
			{
				// Do not call Convert on HibernateException
				throw;
			}
			catch (Exception sqle)
			{
				throw ADOExceptionHelper.Convert(sqle, "unable to select generated column values", selectionSQL);
			}
		}
		// TODO NH: should remove duplication between this and the other overload,
		// probably using H3 approach (adding indirection through IInclusionChecker interface).
		protected string ConcretePropertySelectFragment(string alias, ValueInclusion[] inclusions)
		{
			int propertyCount = entityMetamodel.PropertySpan;
			int[] propertyTableNumbers = PropertyTableNumbersInSelect;
			SelectFragment frag = new SelectFragment(Factory.Dialect);
			for (int i = 0; i < propertyCount; i++)
			{
				if (inclusions[i] != ValueInclusion.None)
				{
					//ie. updateable, not a formula
					frag.AddColumns(
						GenerateTableAlias(alias, propertyTableNumbers[i]),
						propertyColumnNames[i],
						propertyColumnAliases[i]
						);
					frag.AddFormulas(
						GenerateTableAlias(alias, propertyTableNumbers[i]),
						propertyColumnFormulaTemplates[i],
						propertyColumnAliases[i]
						);
				}
			}
			return frag.ToSqlStringFragment();
		}