private object ProcessArrayOrNewCollection(object collection, PersistentCollectionType collectionType) { if (collection == null) { return(null); } ICollectionPersister persister = Session.GetCollectionPersister(collectionType.Role); if (collectionType.IsArrayType) { ArrayHolder ah = Session.GetArrayHolder(collection); if (ah == null) { ah = new ArrayHolder(Session, collection); Session.AddNewCollection(ah, persister); Session.AddArrayHolder(ah); } return(null); } else { PersistentCollection persistentCollection = collectionType.Wrap(Session, collection); Session.AddNewCollection(persistentCollection, persister); if (log.IsDebugEnabled) { log.Debug("Wrapped collection in role: " + collectionType.Role); } return(persistentCollection); //Force a substitution! } }
/// <summary> /// Cascade to the collection elements /// </summary> /// <param name="action"></param> /// <param name="style"></param> /// <param name="collectionType"></param> /// <param name="elemType"></param> /// <param name="child"></param> /// <param name="cascadeVia"></param> /// <param name="session"></param> /// <param name="anything"></param> private static void CascadeCollection( CascadingAction action, CascadeStyle style, PersistentCollectionType collectionType, IType elemType, object child, CascadePoint cascadeVia, ISessionImplementor session, object anything) { // cascade to current collection elements if (log.IsDebugEnabled) { log.Debug("cascading to collection: " + collectionType.Role); } ICollection iter = action.CascadableChildrenCollection(collectionType, child); foreach (object obj in iter) { Cascade(session, obj, elemType, action, style, cascadeVia, anything); } // handle oprhaned entities!! if (style.HasOrphanDelete && action.DeleteOrphans() && child is PersistentCollection) { // We can do the cast since orphan-delete does not apply to: // 1. newly instatiated collections // 2. arrays ( we can't track orphans for detached arrays) DeleteOrphans(child as PersistentCollection, session); } }
protected override object ProcessCollection(object collection, PersistentCollectionType type) { if (collection != null) { SessionImpl session = Session; PersistentCollection coll; if (type.IsArrayType) { coll = session.GetArrayHolder(collection); // if no array holder we found an unwrappered array (this can't occur, // because we now always call wrap() before getting to here) // return (ah==null) ? true : searchForDirtyCollections(ah, type); } else { // if not wrappered yet, its dirty (this can't occur, because // we now always call wrap() before getting to here) // return ( ! (obj is PersistentCollection) ) ? // true : SearchForDirtyCollections( (PersistentCollection) obj, type ); coll = (PersistentCollection)collection; } if (session.CollectionIsDirty(coll)) { _dirty = true; return(null); // NOTE: early exit } } return(null); }
protected override object ProcessCollection(object collection, PersistentCollectionType type) { SessionImpl session = Session; object key = Key; ICollectionPersister persister = session.GetCollectionPersister(type.Role); session.RemoveCollection(persister, key); if (collection != null && (collection is PersistentCollection)) { PersistentCollection wrapper = collection as PersistentCollection; wrapper.SetCurrentSession(session); if (wrapper.WasInitialized) { session.AddNewCollection(wrapper, persister); } else { session.ReattachCollection(wrapper, wrapper.CollectionSnapshot); } } else { // otherwise a null or brand new collection // this will also (inefficiently) handle arrays, which // have no snapshot, so we can't do any better //processArrayOrNewCollection(collection, type); } return(null); }
/// <summary> /// Cascade an action to the child or children /// </summary> /// <param name="session"></param> /// <param name="child"></param> /// <param name="type"></param> /// <param name="action"></param> /// <param name="style"></param> /// <param name="cascadeTo"></param> /// <param name="anything"></param> private static void Cascade( ISessionImplementor session, object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, object anything) { if (child != null) { if (type.IsAssociationType) { if ((( IAssociationType )type).ForeignKeyType.CascadeNow(cascadeTo)) { if (type.IsEntityType || type.IsObjectType) { action.Cascade(session, child, anything); } else if (type.IsPersistentCollectionType) { CascadePoint cascadeVia; if (cascadeTo == CascadePoint.CascadeAfterInsertBeforeDelete) { cascadeVia = CascadePoint.CascadeAfterInsertBeforeDeleteViaCollection; } else { cascadeVia = cascadeTo; } PersistentCollectionType pctype = ( PersistentCollectionType )type; ICollectionPersister persister = session.Factory.GetCollectionPersister(pctype.Role); IType elemType = persister.ElementType; // cascade to current collection elements if (elemType.IsEntityType || elemType.IsObjectType || elemType.IsComponentType) { CascadeCollection(action, style, pctype, elemType, child, cascadeVia, session, anything); } } } } else if (type.IsComponentType) { IAbstractComponentType ctype = (( IAbstractComponentType )type); object[] children = ctype.GetPropertyValues(child, session); IType[] types = ctype.Subtypes; for (int i = 0; i < types.Length; i++) { CascadeStyle componentPropertyStyle = ctype.Cascade(i); if (componentPropertyStyle.DoCascade(action)) { Cascade(session, children[i], types[i], action, componentPropertyStyle, cascadeTo, anything); } } } } }
protected override object ProcessCollection(object collection, PersistentCollectionType type) { if (collection != null) { Session.EvictCollection(collection, type); } return(null); }
internal static ICollection GetLoadedElementsCollection(PersistentCollectionType collectionType, object collection) { if (CollectionIsInitialized(collection)) { // handles arrays and newly instantiated collections return(collectionType.GetElementsCollection(collection)); } else { // does not handle arrays (that's ok, cos they can't be lazy) // or newly instantiated collections so we can do the cast return(((PersistentCollection)collection).QueuedAddsCollection); } }
protected override object ProcessCollection(object collection, PersistentCollectionType collectionType) { if (collection != null && (collection is PersistentCollection)) { PersistentCollection coll = collection as PersistentCollection; if (coll.SetCurrentSession(Session)) { Session.ReattachCollection(coll, coll.CollectionSnapshot); } return(null); } else { return(ProcessArrayOrNewCollection(collection, collectionType)); } }
protected override object ProcessCollection(object collection, PersistentCollectionType type) { ICollectionPersister persister = Session.GetCollectionPersister(type.Role); if (collection == null) { // Do nothing } else if (collection is PersistentCollection) { PersistentCollection coll = (PersistentCollection)collection; if (coll.SetCurrentSession(Session)) { ICollectionSnapshot snapshot = coll.CollectionSnapshot; if (SessionImpl.IsOwnerUnchanged(snapshot, persister, this.Key)) { // a "detached" collection that originally belonged to the same entity if (snapshot.Dirty) { throw new HibernateException("reassociated object has dirty collection"); } Session.ReattachCollection(coll, snapshot); } else { // a "detached" collection that belonged to a different entity throw new HibernateException("reassociated object has dirty collection reference"); } } else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() throw new HibernateException("reassociated object has dirty collection reference"); } } else { // brand new collection //TODO: or an array!! we can't lock objects with arrays now?? throw new HibernateException("reassociated object has dirty collection reference"); } return(null); }
protected override object ProcessCollection(object collection, PersistentCollectionType type) { ICollectionPersister persister = Session.GetCollectionPersister(type.Role); if (collection is PersistentCollection) { PersistentCollection wrapper = (PersistentCollection)collection; if (wrapper.SetCurrentSession(Session)) { //a "detached" collection! ICollectionSnapshot snapshot = wrapper.CollectionSnapshot; if (!SessionImpl.IsOwnerUnchanged(snapshot, persister, Key)) { // if the collection belonged to a different entity, // clean up the existing state of the collection Session.RemoveCollection(persister, Key); } Session.ReattachCollection(wrapper, snapshot); } else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() Session.RemoveCollection(persister, Key); } } else { // null or brand new collection // this will also (inefficiently) handle arrays, which have // no snapshot, so we can't do any better Session.RemoveCollection(persister, Key); //processArrayOrNewCollection(collection, type); } return(null); }
protected override object ProcessCollection(object collection, PersistentCollectionType type) { if (log.IsDebugEnabled) { log.Debug(string.Format("Processing collection for role {0}", type.Role)); } if (collection != null) { PersistentCollection coll; if (type.IsArrayType) { coll = Session.GetArrayHolder(collection); } else { coll = (PersistentCollection)collection; } Session.UpdateReachableCollection(coll, type, _owner); } return(null); }
internal static ICollection GetAllElementsCollection(PersistentCollectionType collectionType, object collection) { return(collectionType.GetElementsCollection(collection)); }
public AbstractCollectionPersister(Mapping.Collection collection, ISessionFactoryImplementor factory) { this.factory = factory; dialect = factory.Dialect; //sqlExceptionConverter = factory.SQLExceptionConverter; collectionType = collection.CollectionType; role = collection.Role; ownerClass = collection.OwnerClass; Alias alias = new Alias("__"); sqlOrderByString = collection.OrderBy; hasOrder = sqlOrderByString != null; sqlOrderByStringTemplate = hasOrder ? Template.RenderOrderByStringTemplate(sqlOrderByString, dialect) : null; sqlWhereString = collection.Where; hasWhere = sqlWhereString != null; sqlWhereStringTemplate = hasWhere ? Template.RenderWhereStringTemplate(sqlWhereString, dialect) : null; hasOrphanDelete = collection.OrphanDelete; batchSize = collection.BatchSize; cache = collection.Cache; 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.Alias(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; IValue element = collection.Element; int elementSpan = element.ColumnSpan; ICollection iter = element.ColumnCollection; Table table = collection.CollectionTable; enableJoinedFetch = element.OuterJoinFetchSetting; elementType = element.Type; if (!collection.IsOneToMany) { CheckColumnDuplication(distinctColumns, element.ColumnCollection); } if (elementType.IsEntityType) { elementPersister = factory.GetPersister((( EntityType )elementType).AssociatedClass); } else { elementPersister = null; } qualifiedTableName = table.GetQualifiedName(dialect, factory.DefaultSchema); string[] aliases = new string[elementSpan]; elementColumnNames = new string[elementSpan]; int j = 0; foreach (Column col in iter) { elementColumnNames[j] = col.GetQuotedName(dialect); aliases[j] = col.Alias(dialect); j++; } elementColumnAliases = alias.ToAliasStrings(aliases, dialect); IType selectColumns; string[] selectType; 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.Alias(dialect); indexColumnNames[i] = indexCol.GetQuotedName(dialect); i++; } selectType = indexColumnNames; selectColumns = indexType; indexColumnAliases = alias.ToAliasStrings(indexAliases, dialect); CheckColumnDuplication(distinctColumns, indexedCollection.Index.ColumnCollection); } else { indexType = null; indexColumnNames = null; indexColumnAliases = null; selectType = elementColumnNames; selectColumns = elementType; } 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); selectType = new string[] { identifierColumnName }; selectColumns = identifierType; identifierColumnAlias = alias.ToAliasString(col.Alias(dialect), dialect); unquotedIdentifierColumnName = identifierColumnAlias; identifierGenerator = idColl.Identifier.CreateIdentifierGenerator(dialect); CheckColumnDuplication(distinctColumns, idColl.Identifier.ColumnCollection); } else { identifierType = null; identifierColumnName = null; identifierColumnAlias = null; unquotedIdentifierColumnName = null; identifierGenerator = null; } rowSelectColumnNames = selectType; rowSelectType = selectColumns; sqlDeleteString = GenerateDeleteString(); sqlInsertRowString = GenerateInsertRowString(); sqlUpdateRowString = GenerateUpdateRowString(); sqlDeleteRowString = GenerateDeleteRowString(); 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; } initializer = CreateCollectionInitializer(factory); if (elementType.IsComponentType) { elementPropertyMapping = new CompositeElementPropertyMapping(elementColumnNames, ( IAbstractComponentType )elementType, factory); } else if (!elementType.IsEntityType) { elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType); } else { IClassPersister persister = factory.GetPersister((( EntityType )elementType).AssociatedClass); // Not all classpersisters implement IPropertyMapping! if (persister is IPropertyMapping) { elementPropertyMapping = ( IPropertyMapping )persister; } else { elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType); } } }
/// <summary> /// Visit a collection. Default superclass implementation is a no-op. /// </summary> /// <param name="collection"></param> /// <param name="type"></param> /// <returns></returns> protected virtual object ProcessCollection(object collection, PersistentCollectionType type) { return(null); }
public override ICollection CascadableChildrenCollection(PersistentCollectionType collectionType, object collection) { // saves / updates don't cascade to uninitialized collections return(Cascades.GetLoadedElementsCollection(collectionType, collection)); }
public override ICollection CascadableChildrenCollection(PersistentCollectionType collectionType, object collection) { return(Cascades.GetLoadedElementsCollection(collectionType, collection)); }
/// <summary> /// The children to whom we should cascade. /// </summary> public abstract ICollection CascadableChildrenCollection(PersistentCollectionType collectionType, object collection);