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