public SingleTableEntityPersister(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping) : base(persistentClass, cache, factory) { #region CLASS + TABLE joinSpan = persistentClass.JoinClosureSpan + 1; qualifiedTableNames = new string[joinSpan]; isInverseTable = new bool[joinSpan]; isNullableTable = new bool[joinSpan]; keyColumnNames = new string[joinSpan][]; Table table = persistentClass.RootTable; qualifiedTableNames[0] = table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); isInverseTable[0] = false; isNullableTable[0] = false; keyColumnNames[0] = IdentifierColumnNames; cascadeDeleteEnabled = new bool[joinSpan]; // Custom sql customSQLInsert = new SqlString[joinSpan]; customSQLUpdate = new SqlString[joinSpan]; customSQLDelete = new SqlString[joinSpan]; insertCallable = new bool[joinSpan]; updateCallable = new bool[joinSpan]; deleteCallable = new bool[joinSpan]; insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan]; updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan]; deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan]; customSQLInsert[0] = persistentClass.CustomSQLInsert; insertCallable[0] = customSQLInsert[0] != null && persistentClass.IsCustomInsertCallable; insertResultCheckStyles[0] = persistentClass.CustomSQLInsertCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLInsert[0], insertCallable[0]); customSQLUpdate[0] = persistentClass.CustomSQLUpdate; updateCallable[0] = customSQLUpdate[0] != null && persistentClass.IsCustomUpdateCallable; updateResultCheckStyles[0] = persistentClass.CustomSQLUpdateCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLUpdate[0], updateCallable[0]); customSQLDelete[0] = persistentClass.CustomSQLDelete; deleteCallable[0] = customSQLDelete[0] != null && persistentClass.IsCustomDeleteCallable; deleteResultCheckStyles[0] = persistentClass.CustomSQLDeleteCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLDelete[0], deleteCallable[0]); #endregion #region JOINS int j = 1; foreach (Join join in persistentClass.JoinClosureIterator) { qualifiedTableNames[j] = join.Table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); isInverseTable[j] = join.IsInverse; isNullableTable[j] = join.IsOptional; cascadeDeleteEnabled[j] = join.Key.IsCascadeDeleteEnabled && factory.Dialect.SupportsCascadeDelete; customSQLInsert[j] = join.CustomSQLInsert; insertCallable[j] = customSQLInsert[j] != null && join.IsCustomInsertCallable; insertResultCheckStyles[j] = join.CustomSQLInsertCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLInsert[j], insertCallable[j]); customSQLUpdate[j] = join.CustomSQLUpdate; updateCallable[j] = customSQLUpdate[j] != null && join.IsCustomUpdateCallable; updateResultCheckStyles[j] = join.CustomSQLUpdateCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLUpdate[j], updateCallable[j]); customSQLDelete[j] = join.CustomSQLDelete; deleteCallable[j] = customSQLDelete[j] != null && join.IsCustomDeleteCallable; deleteResultCheckStyles[j] = join.CustomSQLDeleteCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLDelete[j], deleteCallable[j]); IEnumerable <Column> enumerableKeyCol = new SafetyEnumerable <Column>(join.Key.ColumnIterator); List <string> kcName = new List <string>(join.Key.ColumnSpan); foreach (Column col in enumerableKeyCol) { kcName.Add(col.GetQuotedName(factory.Dialect)); } keyColumnNames[j] = kcName.ToArray(); j++; } constraintOrderedTableNames = new string[qualifiedTableNames.Length]; constraintOrderedKeyColumnNames = new string[qualifiedTableNames.Length][]; for (int i = qualifiedTableNames.Length - 1, position = 0; i >= 0; i--, position++) { constraintOrderedTableNames[position] = qualifiedTableNames[i]; constraintOrderedKeyColumnNames[position] = keyColumnNames[i]; } spaces = ArrayHelper.Join(qualifiedTableNames, ArrayHelper.ToStringArray(persistentClass.SynchronizedTables)); bool lazyAvailable = IsInstrumented(EntityMode.Poco); bool hasDeferred = false; List <string> subclassTables = new List <string>(); List <string[]> joinKeyColumns = new List <string[]>(); List <bool> isConcretes = new List <bool>(); List <bool> isDeferreds = new List <bool>(); List <bool> isInverses = new List <bool>(); List <bool> isNullables = new List <bool>(); List <bool> isLazies = new List <bool>(); subclassTables.Add(qualifiedTableNames[0]); joinKeyColumns.Add(IdentifierColumnNames); isConcretes.Add(true); isDeferreds.Add(false); isInverses.Add(false); isNullables.Add(false); isLazies.Add(false); foreach (Join join in persistentClass.SubclassJoinClosureIterator) { isConcretes.Add(persistentClass.IsClassOrSuperclassJoin(join)); isDeferreds.Add(join.IsSequentialSelect); isInverses.Add(join.IsInverse); isNullables.Add(join.IsOptional); isLazies.Add(lazyAvailable && join.IsLazy); if (join.IsSequentialSelect && !persistentClass.IsClassOrSuperclassJoin(join)) { hasDeferred = true; } subclassTables.Add(join.Table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName)); IEnumerable <Column> enumerableKeyCol = new SafetyEnumerable <Column>(join.Key.ColumnIterator); List <string> keyCols = new List <string>(join.Key.ColumnSpan); foreach (Column col in enumerableKeyCol) { keyCols.Add(col.GetQuotedName(factory.Dialect)); } joinKeyColumns.Add(keyCols.ToArray()); } subclassTableSequentialSelect = isDeferreds.ToArray(); subclassTableNameClosure = subclassTables.ToArray(); subclassTableIsLazyClosure = isLazies.ToArray(); subclassTableKeyColumnClosure = joinKeyColumns.ToArray(); isClassOrSuperclassTable = isConcretes.ToArray(); isInverseSubclassTable = isInverses.ToArray(); isNullableSubclassTable = isNullables.ToArray(); hasSequentialSelects = hasDeferred; #endregion #region DISCRIMINATOR if (persistentClass.IsPolymorphic) { IValue discrimValue = persistentClass.Discriminator; if (discrimValue == null) { throw new MappingException("Discriminator mapping required for single table polymorphic persistence"); } forceDiscriminator = persistentClass.IsForceDiscriminator; IEnumerator <ISelectable> iSel = discrimValue.ColumnIterator.GetEnumerator(); iSel.MoveNext(); ISelectable selectable = iSel.Current; if (discrimValue.HasFormula) { Formula formula = (Formula)selectable; discriminatorFormula = formula.FormulaString; discriminatorFormulaTemplate = formula.GetTemplate(factory.Dialect, factory.SQLFunctionRegistry); discriminatorColumnName = null; discriminatorAlias = Discriminator_Alias; } else { Column column = (Column)selectable; discriminatorColumnName = column.GetQuotedName(factory.Dialect); discriminatorAlias = column.GetAlias(factory.Dialect, persistentClass.RootTable); discriminatorFormula = null; discriminatorFormulaTemplate = null; } discriminatorType = persistentClass.Discriminator.Type; if (persistentClass.IsDiscriminatorValueNull) { discriminatorValue = NullDiscriminator; discriminatorSQLValue = InFragment.Null; discriminatorInsertable = false; } else if (persistentClass.IsDiscriminatorValueNotNull) { discriminatorValue = NotNullDiscriminator; discriminatorSQLValue = InFragment.NotNull; discriminatorInsertable = false; } else { discriminatorInsertable = persistentClass.IsDiscriminatorInsertable && !discrimValue.HasFormula; try { IDiscriminatorType dtype = (IDiscriminatorType)discriminatorType; discriminatorValue = dtype.StringToObject(persistentClass.DiscriminatorValue); discriminatorSQLValue = dtype.ObjectToSQLString(discriminatorValue, factory.Dialect); } catch (InvalidCastException cce) { throw new MappingException( string.Format("Illegal discriminator type: {0} of entity {1}", discriminatorType.Name, persistentClass.EntityName), cce); } catch (Exception e) { throw new MappingException("Could not format discriminator value to SQL string of entity " + persistentClass.EntityName, e); } } } else { forceDiscriminator = false; discriminatorInsertable = false; discriminatorColumnName = null; discriminatorAlias = null; discriminatorType = null; discriminatorValue = null; discriminatorSQLValue = null; discriminatorFormula = null; discriminatorFormulaTemplate = null; } #endregion #region PROPERTIES propertyTableNumbers = new int[PropertySpan]; int i2 = 0; foreach (Property prop in persistentClass.PropertyClosureIterator) { propertyTableNumbers[i2++] = persistentClass.GetJoinNumber(prop); } List <int> columnJoinNumbers = new List <int>(); List <int> formulaJoinedNumbers = new List <int>(); List <int> propertyJoinNumbers = new List <int>(); foreach (Property prop in persistentClass.SubclassPropertyClosureIterator) { int join = persistentClass.GetJoinNumber(prop); propertyJoinNumbers.Add(join); //propertyTableNumbersByName.put( prop.getName(), join ); propertyTableNumbersByNameAndSubclass[prop.PersistentClass.EntityName + '.' + prop.Name] = join; foreach (ISelectable thing in prop.ColumnIterator) { if (thing.IsFormula) { formulaJoinedNumbers.Add(join); } else { columnJoinNumbers.Add(join); } } } subclassColumnTableNumberClosure = columnJoinNumbers.ToArray(); subclassFormulaTableNumberClosure = formulaJoinedNumbers.ToArray(); subclassPropertyTableNumberClosure = propertyJoinNumbers.ToArray(); int subclassSpan = persistentClass.SubclassSpan + 1; subclassClosure = new string[subclassSpan]; subclassClosure[0] = EntityName; if (persistentClass.IsPolymorphic) { subclassesByDiscriminatorValue[discriminatorValue] = EntityName; } #endregion #region SUBCLASSES if (persistentClass.IsPolymorphic) { int k = 1; foreach (Subclass sc in persistentClass.SubclassIterator) { subclassClosure[k++] = sc.EntityName; if (sc.IsDiscriminatorValueNull) { subclassesByDiscriminatorValue[NullDiscriminator] = sc.EntityName; } else if (sc.IsDiscriminatorValueNotNull) { subclassesByDiscriminatorValue[NotNullDiscriminator] = sc.EntityName; } else { if (discriminatorType == null) { throw new MappingException("Not available discriminator type of entity " + persistentClass.EntityName); } try { IDiscriminatorType dtype = (IDiscriminatorType)discriminatorType; subclassesByDiscriminatorValue[dtype.StringToObject(sc.DiscriminatorValue)] = sc.EntityName; } catch (InvalidCastException cce) { throw new MappingException( string.Format("Illegal discriminator type: {0} of entity {1}", discriminatorType.Name, persistentClass.EntityName), cce); } catch (Exception e) { throw new MappingException("Error parsing discriminator value of entity " + persistentClass.EntityName, e); } } } } #endregion InitLockers(); InitSubclassPropertyAliasesMap(persistentClass); PostConstruct(mapping); }