From: Michael D. <mik...@us...> - 2004-05-06 13:14:11
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Type In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22817/NHibernate/Type Modified Files: ComponentType.cs PersistentCollectionType.cs Log Message: Removed hacks that were added because of multiple open IDataReaders throwing exceptions with MsSql. Index: PersistentCollectionType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/PersistentCollectionType.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PersistentCollectionType.cs 26 Apr 2004 03:45:09 -0000 1.9 --- PersistentCollectionType.cs 6 May 2004 13:14:03 -0000 1.10 *************** *** 11,15 **** /// <summary> ! /// A specific PersistentCollectionType for a Role. /// </summary> public abstract class PersistentCollectionType : AbstractType, IAssociationType { --- 11,15 ---- /// <summary> ! /// PersistentCollectionType. /// </summary> public abstract class PersistentCollectionType : AbstractType, IAssociationType { *************** *** 41,108 **** } - /// <summary> - /// Returns a fully initialized Collection - be careful when calling this because it might - /// open another DataReader!!! - /// </summary> - /// <param name="rs"></param> - /// <param name="name"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> public override object NullSafeGet(IDataReader rs, string[] name, ISessionImplementor session, object owner) { return ResolveIdentifier( Hydrate(rs, name, session, owner), session, owner ); } - /// <summary> - /// Gets a Collection without opening a DataReader. - /// </summary> - /// <param name="rs"></param> - /// <param name="name"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <param name="partOfComponent"></param> - /// <returns> - /// The Collection returned from here is a lazy-load Collection regardless of what the map says. To - /// load this Collection partOfComponent must be true and then ResolveIdentifier must be called. This - /// method is only intended to be used by ComponentType to solve the problem of Getting a Collection - /// opens a second DataReader. - /// </returns> - public object NullSafeGet(IDataReader rs, string[] name, ISessionImplementor session, object owner, bool partOfComponent) - { - object id = session.GetEntityIdentifier(owner); - PersistentCollection collection = session.GetLoadingCollection(role, id); - if(collection!=null) return collection.GetCachedValue(); //TODO: yuck... call another method - H2.0.3comment - - CollectionPersister persister = session.Factory.GetCollectionPersister(role); - collection = persister.GetCachedCollection(id, owner, session); - if(collection!=null) - { - session.AddInitializedCollection(collection, persister, id); - return collection.GetCachedValue(); - } - else - { - - collection = Instantiate(session, persister); - session.AddUninitializedCollection(collection, persister, id); - - // hard coding in lazy here because we don't want it to load during it's Get - just - // initialize the Collection class as if it is being lazy loaded - we'll get back to - // loading it during ResolveIdentifier... - collection.GetInitialValue(true); - - // if we get to here then we have just created a lazy loaded (ie - uninitialized )Collection that might - // be a part of a Component. If it is part of a component then we need to mark it as - // needing to be a part of the batch that gets ResolveIdentifier called where it will be Initialized - // according to the IsLazy property of the Persister - if(partOfComponent) - { - session.AddUnresolvedComponentCollection(id, role, collection); - } - - return collection; - } - } - public virtual object GetCollection(object id, object owner, ISessionImplementor session) { PersistentCollection collection = session.GetLoadingCollection(role, id); --- 41,48 ---- *************** *** 216,228 **** } - /// <summary> - /// - /// </summary> - /// <param name="value">The id of the owner.</param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> - /// <remarks> - /// </remarks> public override object ResolveIdentifier(object value, ISessionImplementor session, object owner) { if (value==null) { --- 156,159 ---- *************** *** 234,278 **** } - /// <summary> - /// Resolves Collection that might be part of a Component. - /// </summary> - /// <param name="value">The id of the owner.</param> - /// <param name="session">The current Session.</param> - /// <param name="owner">The owner of the collection.</param> - /// <param name="partOfComponent">Indicates if this Collection is a part of a Component.</param> - /// <returns>A fully initialized collection according to its Persister's IsLazy property.</returns> - public object ResolveIdentifier(object value, ISessionImplementor session, object owner, bool partOfComponent) - { - if(partOfComponent==false) return ResolveIdentifier(value, session, owner); - - // check to see if this Collection is part of a Component and it has already been Instantiated - // and just needs to GetInitialValue because it has already been Instantiated and Added to the - // Session in NullSafeGet - object id = value; - - PersistentCollection collection = session.GetUnresolvedComponentCollection(id, role); - - if(collection==null) - { - // when the collection is null that means it is not an UnresolvedComponentCollection - // so we can let ResolveIdentifier get it however it needs to. - return ResolveIdentifier(id, session, owner); - } - else - { - // we already have a collection - CollectionPersister persister = session.Factory.GetCollectionPersister(role); - collection.GetInitialValue(persister.IsLazy); - - // we have resolved the Collection in the Component so remove it from the unresolved - session.RemoveUnresolvedComponentCollection(id, role); - - return collection; - } - - - - } - public virtual bool IsArrayType { get { return false; } --- 165,168 ---- Index: ComponentType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/ComponentType.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ComponentType.cs 26 Apr 2004 03:45:09 -0000 1.7 --- ComponentType.cs 6 May 2004 13:14:03 -0000 1.8 *************** *** 112,164 **** } ! /// <summary> ! /// Provides component specific implementation of ResolveIdentifier that is safe for Collections. ! /// </summary> ! /// <param name="value">The Component object.</param> ! /// <param name="session">The current Session.</param> ! /// <param name="owner">The Entity object the Component is contained in.</param> ! /// <returns>A fully resolved Component.</returns> ! public override object ResolveIdentifier(object value, ISessionImplementor session, object owner) ! { ! if(value==null) return null; ! ! for(int i=0; i < propertySpan; i++) ! { ! // the only types we need to resolve are PersistentCollectionTypes and ComponentTypes. ! // ComponentTypes only really need to be resolved when they contain other ComponentTypes ! // that contain Collections, I'm not sure how safe it is to call Set(target, val) during ! // ResolveIdentifier - commented out the Set because this is not creating new objects, just ! // modifying the existing ones so they don't need to be Set again. ! // Nor am I sure how safe it is to ignore ResolveIdentifer for everything ! // else. I know ManyToOneType and OneToOneType also override ResolveIdentifer and can potentially ! // connect to the db. ! ! if(types[i] is PersistentCollectionType) ! { ! object id = session.GetEntityIdentifier(owner); ! object val = ((PersistentCollectionType)types[i]).ResolveIdentifier(id, session, owner, true); ! //setters[i].Set(value, val); ! } ! else ! { ! object val = types[i].ResolveIdentifier(getters[i].Get(value), session, owner); ! //setters[i].Set(value, val); ! } ! } ! ! return value; ! ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="rs"></param> ! /// <param name="names"></param> ! /// <param name="session"></param> ! /// <param name="owner"></param> ! /// <returns></returns> ! public override object NullSafeGet(IDataReader rs, string[] names, ISessionImplementor session, object owner) ! { int begin = 0; bool notNull=false; --- 112,116 ---- } ! public override object NullSafeGet(IDataReader rs, string[] names, ISessionImplementor session, object owner) { int begin = 0; bool notNull=false; *************** *** 167,187 **** int length = types[i].GetColumnSpan( session.Factory ); string[] range = ArrayHelper.Slice(names, begin, length); ! object val = null; //types[i].NullSafeGet(rs, range, session, owner); ! ! // if the Component contains a collection type then use its special NullSafeGet ! // so that we don't create another IDataReader to Get the Collections values from ! // the Db. This breaks the nice OO'ness of being able to just call type.NullSafeGet ! // but it solves the problem of Collections inside of Components opening another ! // DataReader... ! if(types[i] is PersistentCollectionType) ! { ! val = ((PersistentCollectionType)types[i]).NullSafeGet(rs, range, session, owner, true); ! } ! else ! { ! val = types[i].NullSafeGet(rs, range, session, owner); ! } ! ! if (val!=null) notNull=true; values[i] = val; --- 119,123 ---- int length = types[i].GetColumnSpan( session.Factory ); string[] range = ArrayHelper.Slice(names, begin, length); ! object val = types[i].NullSafeGet(rs, range, session, owner); if (val!=null) notNull=true; values[i] = val; |