From: Michael D. <mik...@us...> - 2004-10-03 18:07:38
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7021/Impl Modified Files: Tag: alpha_avalon-proxy SessionImpl.cs Log Message: serialization of proxies is now working. Index: SessionImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionImpl.cs,v retrieving revision 1.44.2.1 retrieving revision 1.44.2.2 diff -C2 -d -r1.44.2.1 -r1.44.2.2 *** SessionImpl.cs 27 Sep 2004 03:42:02 -0000 1.44.2.1 --- SessionImpl.cs 3 Oct 2004 16:58:14 -0000 1.44.2.2 *************** *** 47,50 **** --- 47,58 ---- private IDictionary proxiesByKey; //key=Key, value=HibernateProxy + // these are used to serialize the proxiesByKey Dictionary - I was not able to + // have a Hashtable serialize fully by the time that SessionImpl OnDeserialization + // was getting called - I think I'm not completely understanding the sequence of + // deserialization events. When SessionImpl was getting the OnDeserialization called + // the proxies were not fully deserialized. + private ArrayList tmpProxiesKey; + private ArrayList tmpProxiesProxy; + //IdentityMaps are serializable in NH private IdentityMap entries;//key=Object, value=Entry *************** *** 386,389 **** --- 394,399 ---- protected SessionImpl(SerializationInfo info, StreamingContext context) { + log.Info( "recreating session from special ctor used during deserialization" ); + this.factory = (SessionFactoryImpl)info.GetValue( "factory", typeof(SessionFactoryImpl) ); this.autoClose = info.GetBoolean("autoClose"); *************** *** 393,397 **** this.callAfterTransactionCompletionFromDisconnect = info.GetBoolean("callAfterTransactionCompletionFromDisconnect"); this.entitiesByKey = (IDictionary)info.GetValue( "entitiesByKey", typeof(IDictionary) ); ! this.proxiesByKey = (IDictionary)info.GetValue( "proxiesByKey", typeof(IDictionary) ); this.nullifiables = (IDictionary)info.GetValue( "nullifiables", typeof(IDictionary) ); this.interceptor = (IInterceptor)info.GetValue( "interceptor", typeof(IInterceptor) ); --- 403,413 ---- this.callAfterTransactionCompletionFromDisconnect = info.GetBoolean("callAfterTransactionCompletionFromDisconnect"); this.entitiesByKey = (IDictionary)info.GetValue( "entitiesByKey", typeof(IDictionary) ); ! ! // we did not actually serializing the IDictionary but instead the proxies in an arraylist ! // because of deserailization issues I couldn't figure out. ! //this.proxiesByKey = (IDictionary)info.GetValue( "proxiesByKey", typeof(IDictionary) ); ! tmpProxiesKey = (ArrayList)info.GetValue( "tmpProxiesKey", typeof(ArrayList) ); ! tmpProxiesProxy = (ArrayList)info.GetValue( "tmpProxiesProxy", typeof(ArrayList) ); ! this.nullifiables = (IDictionary)info.GetValue( "nullifiables", typeof(IDictionary) ); this.interceptor = (IInterceptor)info.GetValue( "interceptor", typeof(IInterceptor) ); *************** *** 415,424 **** void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { ! if ( IsConnected ) throw new InvalidOperationException("Cannot serialize a Session while connected"); ! if ( insertions.Count!=0 || deletions.Count!=0 ) throw new InvalidOperationException("Cannot serialize a Session which has work waiting to be flushed"); - log.Info("serializing session"); - info.AddValue( "factory", factory, typeof(SessionFactoryImpl) ); info.AddValue( "autoClose", autoClose ); --- 431,446 ---- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { ! log.Info( "writting session to serializer" ); ! ! if ( IsConnected ) ! { ! throw new InvalidOperationException("Cannot serialize a Session while connected"); ! } ! ! if ( insertions.Count!=0 || deletions.Count!=0 ) ! { throw new InvalidOperationException("Cannot serialize a Session which has work waiting to be flushed"); + } info.AddValue( "factory", factory, typeof(SessionFactoryImpl) ); info.AddValue( "autoClose", autoClose ); *************** *** 428,432 **** info.AddValue( "callAfterTransactionCompletionFromDisconnect", callAfterTransactionCompletionFromDisconnect ); info.AddValue( "entitiesByKey", entitiesByKey, typeof(IDictionary) ); ! info.AddValue( "proxiesByKey", proxiesByKey, typeof(IDictionary) ); info.AddValue( "nullifiables", nullifiables, typeof(IDictionary) ); info.AddValue( "interceptor", interceptor, typeof(IInterceptor) ); --- 450,470 ---- info.AddValue( "callAfterTransactionCompletionFromDisconnect", callAfterTransactionCompletionFromDisconnect ); info.AddValue( "entitiesByKey", entitiesByKey, typeof(IDictionary) ); ! ! // the IDictionary should not be serialized because the objects inside of it are not ! // fully deserialized until after the session is deserialized. Instead use two ArrayList ! // to hold the values because they don't have the deserialization complexities that ! // hashtables do. ! //info.AddValue( "proxiesByKey", proxiesByKey, typeof(IDictionary) ); ! tmpProxiesKey = new ArrayList( proxiesByKey.Count ); ! tmpProxiesProxy = new ArrayList( proxiesByKey.Count ); ! foreach(DictionaryEntry de in proxiesByKey) ! { ! tmpProxiesKey.Add( de.Key ); ! tmpProxiesProxy.Add( de.Value ); ! } ! ! info.AddValue( "tmpProxiesKey", tmpProxiesKey ); ! info.AddValue( "tmpProxiesProxy", tmpProxiesProxy ); ! info.AddValue( "nullifiables", nullifiables, typeof(IDictionary) ); info.AddValue( "interceptor", interceptor, typeof(IInterceptor) ); *************** *** 448,452 **** void IDeserializationCallback.OnDeserialization(Object sender) { ! log.Info("deserializing session"); // don't need any section for IdentityMaps because .net does not have a problem --- 486,490 ---- void IDeserializationCallback.OnDeserialization(Object sender) { ! log.Info("OnDeserialization of the session."); // don't need any section for IdentityMaps because .net does not have a problem *************** *** 469,476 **** } ! // TODO: figure out why proxies are having problems. The enumerator appears to be throwing ! // a null reference exception when the proxiesByKey.Count==0 ! foreach(object proxy in proxiesByKey.Values) { if (proxy is INHibernateProxy) { --- 507,527 ---- } ! ! // recreate the proxiesByKey hashtable from the two arraylists. ! proxiesByKey = new Hashtable( tmpProxiesKey.Count ); ! for(int i=0; i<tmpProxiesKey.Count; i++) { + proxiesByKey.Add( tmpProxiesKey[i], tmpProxiesProxy[i] ); + } + + // we can't remove an entry from an IDictionary while enumerating so store the ones + // to remove in this list + ArrayList keysToRemove = new ArrayList(); + + foreach( DictionaryEntry de in proxiesByKey ) + { + object key = de.Key; + object proxy = de.Value; + if (proxy is INHibernateProxy) { *************** *** 479,487 **** else { ! // the proxy was pruned during the serialization process ! proxiesByKey.Remove(proxy); } } foreach(EntityEntry e in entries.Values) { --- 530,545 ---- else { ! // the proxy was pruned during the serialization process because ! // the target had been instantiated. ! keysToRemove.Add( key ); } } + for( int i=0; i<keysToRemove.Count; i++ ) + { + proxiesByKey.Remove( keysToRemove[i] ); + } + + foreach(EntityEntry e in entries.Values) { |