public static IExpectation AppropriateExpectation(ExecuteUpdateResultCheckStyle style) { if (style == ExecuteUpdateResultCheckStyle.None) { return None; } else if (style == ExecuteUpdateResultCheckStyle.Count) { return Basic; } else { throw new HibernateException("unknown check style : " + style); } }
public void SetCustomSQLUpdate(string sql, bool callable, ExecuteUpdateResultCheckStyle checkStyle) { customSQLUpdate = SqlString.Parse(sql); customUpdateCallable = callable; updateCheckStyle = checkStyle; }
public void SetCustomSQLInsert(string sql, bool callable, ExecuteUpdateResultCheckStyle checkStyle) { customSQLInsert = SqlString.Parse(sql); customInsertCallable = callable; insertCheckStyle = checkStyle; }
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); }
public void SetCustomSQLDeleteAll(string sql, bool callable, ExecuteUpdateResultCheckStyle checkStyle) { customSQLDeleteAll = SqlString.Parse(sql); customDeleteAllCallable = callable; deleteAllCheckStyle = checkStyle; }
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(); }
/// <summary> /// Constructs the NormalizedEntityPerister for the PersistentClass. /// </summary> /// <param name="persistentClass">The PersistentClass to create the EntityPersister for.</param> /// <param name="cache">The configured <see cref="ICacheConcurrencyStrategy" />.</param> /// <param name="factory">The SessionFactory that this EntityPersister will be stored in.</param> /// <param name="mapping">The mapping used to retrieve type information.</param> public JoinedSubclassEntityPersister(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping) : base(persistentClass, cache, factory) { #region DISCRIMINATOR if (persistentClass.IsPolymorphic) { try { discriminatorValue = persistentClass.SubclassId; discriminatorSQLString = discriminatorValue.ToString(); } catch (Exception e) { throw new MappingException("Could not format discriminator value to SQL string", e); } } else { discriminatorValue = null; discriminatorSQLString = null; } if (OptimisticLockMode > Versioning.OptimisticLock.Version) throw new MappingException(string.Format("optimistic-lock=all|dirty not supported for joined-subclass mappings [{0}]", EntityName)); #endregion #region MULTITABLES int idColumnSpan = IdentifierColumnSpan; List<string> tables = new List<string>(); List<string[]> keyColumns = new List<string[]>(); List<bool> cascadeDeletes = new List<bool>(); IEnumerator<IKeyValue> kiter = persistentClass.KeyClosureIterator.GetEnumerator(); foreach (Table tab in persistentClass.TableClosureIterator) { kiter.MoveNext(); IKeyValue key = kiter.Current; string tabname = tab.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); tables.Add(tabname); List<string> keyCols = new List<string>(idColumnSpan); IEnumerable<Column> enumerableKCols = new SafetyEnumerable<Column>(key.ColumnIterator); foreach (Column kcol in enumerableKCols) keyCols.Add(kcol.GetQuotedName(factory.Dialect)); keyColumns.Add(keyCols.ToArray()); cascadeDeletes.Add(key.IsCascadeDeleteEnabled && factory.Dialect.SupportsCascadeDelete); } naturalOrderTableNames = tables.ToArray(); naturalOrderTableKeyColumns = keyColumns.ToArray(); naturalOrderCascadeDeleteEnabled = cascadeDeletes.ToArray(); List<string> subtables = new List<string>(); List<bool> isConcretes = new List<bool>(); keyColumns = new List<string[]>(); foreach (Table tab in persistentClass.SubclassTableClosureIterator) { isConcretes.Add(persistentClass.IsClassOrSuperclassTable(tab)); string tabname = tab.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); subtables.Add(tabname); List<string> key = new List<string>(idColumnSpan); foreach (Column column in tab.PrimaryKey.ColumnIterator) key.Add(column.GetQuotedName(factory.Dialect)); keyColumns.Add(key.ToArray()); } subclassTableNameClosure = subtables.ToArray(); subclassTableKeyColumnClosure = keyColumns.ToArray(); isClassOrSuperclassTable = isConcretes.ToArray(); constraintOrderedTableNames = new string[subclassTableNameClosure.Length]; constraintOrderedKeyColumnNames = new string[subclassTableNameClosure.Length][]; int currentPosition = 0; for (int i = subclassTableNameClosure.Length - 1; i >= 0; i--, currentPosition++) { constraintOrderedTableNames[currentPosition] = subclassTableNameClosure[i]; constraintOrderedKeyColumnNames[currentPosition] = subclassTableKeyColumnClosure[i]; } tableSpan = naturalOrderTableNames.Length; tableNames = Reverse(naturalOrderTableNames); tableKeyColumns = Reverse(naturalOrderTableKeyColumns); Reverse(subclassTableNameClosure, tableSpan); Reverse(subclassTableKeyColumnClosure, tableSpan); spaces = ArrayHelper.Join(tableNames, persistentClass.SynchronizedTables.ToArray()); // Custom sql customSQLInsert = new SqlString[tableSpan]; customSQLUpdate = new SqlString[tableSpan]; customSQLDelete = new SqlString[tableSpan]; insertCallable = new bool[tableSpan]; updateCallable = new bool[tableSpan]; deleteCallable = new bool[tableSpan]; insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan]; updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan]; deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan]; PersistentClass pc = persistentClass; int jk = tableSpan - 1; while (pc != null) { customSQLInsert[jk] = pc.CustomSQLInsert; insertCallable[jk] = customSQLInsert[jk] != null && pc.IsCustomInsertCallable; insertResultCheckStyles[jk] = pc.CustomSQLInsertCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLInsert[jk], insertCallable[jk]); customSQLUpdate[jk] = pc.CustomSQLUpdate; updateCallable[jk] = customSQLUpdate[jk] != null && pc.IsCustomUpdateCallable; updateResultCheckStyles[jk] = pc.CustomSQLUpdateCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLUpdate[jk], updateCallable[jk]); customSQLDelete[jk] = pc.CustomSQLDelete; deleteCallable[jk] = customSQLDelete[jk] != null && pc.IsCustomDeleteCallable; deleteResultCheckStyles[jk] = pc.CustomSQLDeleteCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLDelete[jk], deleteCallable[jk]); jk--; pc = pc.Superclass; } if (jk != -1) { throw new AssertionFailure("Tablespan does not match height of joined-subclass hierarchy."); } #endregion #region PROPERTIES int hydrateSpan = PropertySpan; naturalOrderPropertyTableNumbers = new int[hydrateSpan]; propertyTableNumbers = new int[hydrateSpan]; int i2 = 0; foreach (Property prop in persistentClass.PropertyClosureIterator) { string tabname = prop.Value.Table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); propertyTableNumbers[i2] = GetTableId(tabname, tableNames); naturalOrderPropertyTableNumbers[i2] = GetTableId(tabname, naturalOrderTableNames); i2++; } // subclass closure properties List<int> columnTableNumbers = new List<int>(); List<int> formulaTableNumbers = new List<int>(); List<int> propTableNumbers = new List<int>(); foreach (Property prop in persistentClass.SubclassPropertyClosureIterator) { Table tab = prop.Value.Table; string tabname = tab.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); int tabnum = GetTableId(tabname, subclassTableNameClosure); propTableNumbers.Add(tabnum); foreach (ISelectable thing in prop.ColumnIterator) { if (thing.IsFormula) formulaTableNumbers.Add(tabnum); else columnTableNumbers.Add(tabnum); } } subclassColumnTableNumberClosure = columnTableNumbers.ToArray(); subclassPropertyTableNumberClosure = propTableNumbers.ToArray(); subclassFormulaTableNumberClosure = formulaTableNumbers.ToArray(); #endregion #region SUBCLASSES int subclassSpan = persistentClass.SubclassSpan + 1; subclassClosure = new string[subclassSpan]; subclassClosure[subclassSpan - 1] = EntityName; if (persistentClass.IsPolymorphic) { subclassesByDiscriminatorValue[discriminatorValue] = EntityName; discriminatorValues = new string[subclassSpan]; discriminatorValues[subclassSpan - 1] = discriminatorSQLString; notNullColumnTableNumbers = new int[subclassSpan]; int id = GetTableId( persistentClass.Table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName), subclassTableNameClosure); notNullColumnTableNumbers[subclassSpan - 1] = id; notNullColumnNames = new string[subclassSpan]; notNullColumnNames[subclassSpan - 1] = subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName(); } else { discriminatorValues = null; notNullColumnTableNumbers = null; notNullColumnNames = null; } int k2 = 0; foreach (Subclass sc in persistentClass.SubclassIterator) { subclassClosure[k2] = sc.EntityName; try { if (persistentClass.IsPolymorphic) { // we now use subclass ids that are consistent across all // persisters for a class hierarchy, so that the use of // "foo.class = Bar" works in HQL int subclassId = sc.SubclassId; //new Integer(k+1); subclassesByDiscriminatorValue[subclassId] = sc.EntityName; discriminatorValues[k2] = subclassId.ToString(); int id = GetTableId( sc.Table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName), subclassTableNameClosure); notNullColumnTableNumbers[k2] = id; notNullColumnNames[k2] = subclassTableKeyColumnClosure[id][0]; //( (Column) sc.getTable().getPrimaryKey().getColumnIterator().next() ).getName(); } } catch (Exception e) { throw new MappingException("Error parsing discriminator value", e); } k2++; } #endregion InitLockers(); InitSubclassPropertyAliasesMap(persistentClass); PostConstruct(mapping); }
public UnionSubclassEntityPersister(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping):base(persistentClass, cache, factory) { if (IdentifierGenerator is IdentityGenerator) { throw new MappingException("Cannot use identity column key generation with <union-subclass> mapping for: " + EntityName); } // TABLE tableName = persistentClass.Table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); #region Custom SQL SqlString sql; bool callable; ExecuteUpdateResultCheckStyle checkStyle; sql = persistentClass.CustomSQLInsert; callable = sql != null && persistentClass.IsCustomInsertCallable; checkStyle = sql == null ? ExecuteUpdateResultCheckStyle.Count : (persistentClass.CustomSQLInsertCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(sql, callable)); customSQLInsert = new SqlString[] { sql }; insertCallable = new bool[] { callable }; insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle }; sql = persistentClass.CustomSQLUpdate; callable = sql != null && persistentClass.IsCustomUpdateCallable; checkStyle = sql == null ? ExecuteUpdateResultCheckStyle.Count : (persistentClass.CustomSQLUpdateCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(sql, callable)); customSQLUpdate = new SqlString[] { sql }; updateCallable = new bool[] { callable }; updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle }; sql = persistentClass.CustomSQLDelete; callable = sql != null && persistentClass.IsCustomDeleteCallable; checkStyle = sql == null ? ExecuteUpdateResultCheckStyle.Count : (persistentClass.CustomSQLDeleteCheckStyle ?? ExecuteUpdateResultCheckStyle.DetermineDefault(sql, callable)); customSQLDelete = new SqlString[] { sql }; deleteCallable = new bool[] { callable }; deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle }; #endregion discriminatorValue = persistentClass.SubclassId; discriminatorSQLValue = persistentClass.SubclassId.ToString(); #region PROPERTIES int subclassSpan = persistentClass.SubclassSpan + 1; subclassClosure = new string[subclassSpan]; subclassClosure[0] = EntityName; #endregion #region SUBCLASSES subclassByDiscriminatorValue[persistentClass.SubclassId] = persistentClass.EntityName; if (persistentClass.IsPolymorphic) { int k = 1; foreach (Subclass sc in persistentClass.SubclassIterator) { subclassClosure[k++] = sc.EntityName; subclassByDiscriminatorValue[sc.SubclassId] = sc.EntityName; } } #endregion #region SPACES //TODO: i'm not sure, but perhaps we should exclude abstract denormalized tables? int spacesSize = 1 + persistentClass.SynchronizedTables.Count; spaces = new string[spacesSize]; spaces[0] = tableName; IEnumerator<string> iSyncTab = persistentClass.SynchronizedTables.GetEnumerator(); for (int i = 1; i < spacesSize; i++) { iSyncTab.MoveNext(); spaces[i] = iSyncTab.Current; } HashedSet<string> subclassTables = new HashedSet<string>(); foreach (Table table in persistentClass.SubclassTableClosureIterator) { subclassTables.Add( table.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName)); } subclassSpaces = new string[subclassTables.Count]; subclassTables.CopyTo(subclassSpaces, 0); subquery = GenerateSubquery(persistentClass, mapping); if (IsMultiTable) { int idColumnSpan = IdentifierColumnSpan; List<string> tableNames = new List<string>(); List<string[]> keyColumns = new List<string[]>(); if (!IsAbstract) { tableNames.Add(tableName); keyColumns.Add(IdentifierColumnNames); } foreach (Table tab in persistentClass.SubclassTableClosureIterator) { if (!tab.IsAbstractUnionTable) { string _tableName = tab.GetQualifiedName(factory.Dialect, factory.Settings.DefaultCatalogName, factory.Settings.DefaultSchemaName); tableNames.Add(_tableName); List<string> key = new List<string>(idColumnSpan); foreach (Column column in tab.PrimaryKey.ColumnIterator) key.Add(column.GetQuotedName(factory.Dialect)); keyColumns.Add(key.ToArray()); } } constraintOrderedTableNames = tableNames.ToArray(); constraintOrderedKeyColumnNames = keyColumns.ToArray(); } else { constraintOrderedTableNames = new string[] { tableName }; constraintOrderedKeyColumnNames = new string[][] { IdentifierColumnNames }; } #endregion InitLockers(); InitSubclassPropertyAliasesMap(persistentClass); PostConstruct(mapping); }
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(); }
//INITIALIZATION: public SingleTableEntityPersister(PersistentClass model, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping) : base(model, cache, factory) { // CLASS + TABLE System.Type mappedClass = model.MappedClass; Table table = model.RootTable; qualifiedTableName = table.GetQualifiedName(Dialect, factory.DefaultSchema); tableNames = new string[] {qualifiedTableName}; // Custom sql customSQLInsert = new SqlString[1]; customSQLUpdate = new SqlString[1]; customSQLDelete = new SqlString[1]; insertCallable = new bool[1]; updateCallable = new bool[1]; deleteCallable = new bool[1]; insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[1]; updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[1]; deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[1]; customSQLInsert[0] = model.CustomSQLInsert; insertCallable[0] = customSQLInsert[0] != null && model.IsCustomInsertCallable; insertResultCheckStyles[0] = model.CustomSQLInsertCheckStyle == null ? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLInsert[0], insertCallable[0]) : model.CustomSQLInsertCheckStyle; customSQLUpdate[0] = model.CustomSQLUpdate; updateCallable[0] = customSQLUpdate[0] != null && model.IsCustomUpdateCallable; updateResultCheckStyles[0] = model.CustomSQLUpdateCheckStyle == null ? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLUpdate[0], updateCallable[0]) : model.CustomSQLUpdateCheckStyle; customSQLDelete[0] = model.CustomSQLDelete; deleteCallable[0] = customSQLDelete[0] != null && model.IsCustomDeleteCallable; deleteResultCheckStyles[0] = model.CustomSQLDeleteCheckStyle == null ? ExecuteUpdateResultCheckStyle.DetermineDefault(customSQLDelete[0], deleteCallable[0]) : model.CustomSQLDeleteCheckStyle; // detect mapping errors HashedSet distinctColumns = new HashedSet(); // DISCRIMINATOR if (model.IsPolymorphic) { IValue d = model.Discriminator; if (d == null) { throw new MappingException("A discriminator mapping required for polymorphic persistence of " + model.Name); } forceDiscriminator = model.IsForceDiscriminator; // the discriminator will have only one column foreach (ISelectable selectable in d.ColumnCollection) { if (d.HasFormula) { Formula formula = (Formula) selectable; discriminatorFormula = formula.FormulaString; discriminatorFormulaTemplate = formula.GetTemplate(factory.Dialect, factory.SQLFunctionRegistry); discriminatorColumnName = null; discriminatorAlias = "clazz_"; } else { Column column = (Column) selectable; discriminatorColumnName = column.GetQuotedName(Dialect); discriminatorAlias = column.GetAlias(Dialect); discriminatorFormula = null; discriminatorFormulaTemplate = null; } } discriminatorType = model.Discriminator.Type; if (model.IsDiscriminatorValueNull) { discriminatorValue = NullDiscriminator; discriminatorSQLValue = InFragment.Null; discriminatorInsertable = false; } else if (model.IsDiscriminatorValueNotNull) { discriminatorValue = NotNullDiscriminator; discriminatorSQLValue = InFragment.NotNull; discriminatorInsertable = false; } else { discriminatorInsertable = model.IsDiscriminatorInsertable && !d.HasFormula; try { IDiscriminatorType dtype = (IDiscriminatorType) discriminatorType; discriminatorValue = dtype.StringToObject(model.DiscriminatorValue); discriminatorSQLValue = dtype.ObjectToSQLString(discriminatorValue); } catch (InvalidCastException) { throw new MappingException(string.Format("Illegal discriminator type: {0}", discriminatorType.Name)); } catch (Exception e) { string msg = String.Format("Could not format discriminator value '{0}' to sql string using the IType {1}", model.DiscriminatorValue, model.Discriminator.Type.ToString()); throw new MappingException(msg, e); } if (discriminatorInsertable) { distinctColumns.Add(discriminatorColumnName); } } } else { forceDiscriminator = false; discriminatorInsertable = false; discriminatorColumnName = null; discriminatorAlias = null; discriminatorType = null; discriminatorValue = null; discriminatorSQLValue = null; } // PROPERTIES HashedSet thisClassProperties = new HashedSet(); foreach (Mapping.Property prop in model.PropertyClosureCollection) { thisClassProperties.Add(prop); } // SQL string generation moved to PostInstantiate int subclassSpan = model.SubclassSpan + 1; subclassClosure = new System.Type[subclassSpan]; subclassClosure[0] = mappedClass; if (model.IsPolymorphic) { subclassesByDiscriminatorValue.Add(discriminatorValue, mappedClass); } // SUBCLASSES if (model.IsPolymorphic) { int k = 1; foreach (Subclass sc in model.SubclassCollection) { subclassClosure[k++] = sc.MappedClass; if (sc.IsDiscriminatorValueNull) { subclassesByDiscriminatorValue.Add(NullDiscriminator, sc.MappedClass); } else if (sc.IsDiscriminatorValueNotNull) { subclassesByDiscriminatorValue.Add(NotNullDiscriminator, sc.MappedClass); } else { try { IDiscriminatorType dtype = discriminatorType as IDiscriminatorType; subclassesByDiscriminatorValue.Add( dtype.StringToObject(sc.DiscriminatorValue), sc.MappedClass); } catch (InvalidCastException) { throw new MappingException(string.Format("Illegal discriminator type: {0}", discriminatorType.Name)); } catch (Exception e) { throw new MappingException(string.Format("Error parsing discriminator value: '{0}'", sc.DiscriminatorValue), e); } } } } // This is in PostInstatiate as it needs identifier info //InitLockers(); propertyTableNumbers = new int[EntityMetamodel.PropertySpan]; for (int i = 0; i < propertyTableNumbers.Length; i++) { propertyTableNumbers[i] = 0; } InitSubclassPropertyAliasesMap(model); PostConstruct(mapping); }