Wait... if the problem was with some proxy the issue is another (probably)
and was fixed few days ago.Btw if you have a test you can create JIRA ticket
attaching the test case.

2009/6/4 Lee Henson <[email protected]>

>
> Ok so:
>
> - SortedSet uses SortedDictionary internally. SortedDictionary does
> not use a Hashtable internally to store it's keys and values, using
> instead a TreeBase. When the entity is inserted into a SortedSet, no
> evaluation of GetHashCode() is made.
> - HashedSet uses Hashtable internally. Hashtable will evaluate
> GetHashCode() on any object placed into it.
>
> Scenario: within user code at runtime, a transient collection has a
> proxy added to it
>
> - if the collection is a SortedSet, no proxy initialization takes
> place
> - if the collection is a HashedSet, the proxy is initialized and any
> onward associations (entities/collections) are added to the session
>
> Scenario: during flush
>
> - SortedSet: PersistentSet.GetSnapshot() is called, placing the
> contents in a Hashtable -> proxies are initialized and exception is
> thrown
> - HashedSet: PersistentSet.GetSnapshot() is called, placing the
> contents in a Hashtable -> proxies are already initialized so no
> exception is thrown
>
> I think this is inconsistent. I can see two alternatives:
>
> 1) if I override GetSnapshot and change the use of Hashtable to
> SortedDictionary, no exception is thrown
>
> public override ICollection GetSnapshot(ICollectionPersister
> persister)
> {
>        EntityMode entityMode = Session.EntityMode;
>
>        //if (set==null) return new Set(session);
>        SortedDictionary<object, object> clonedSet = new
> SortedDictionary<object, object>();
>        foreach (object current in set)
>        {
>                object copied = persister.ElementType.DeepCopy(current,
> entityMode,
> persister.Factory);
>                clonedSet[copied] = copied;
>        }
>        return clonedSet;
> }
>
> However, there are obviously performance implications in using a
> SortedDictionary vs Hashtable as the size of the collection grows.
>
> 2) Call GetHashCode() when an element is added to a DictionarySet:
>
> public override bool Add(T o)
> {
>        if (InternalDictionary.ContainsKey(o))
>        {
>                return false;
>        }
>        else
>        {
>                //The object we are adding is just a placeholder.  The thing
> we are
>                //really concerned with is 'o', the key.
>                InternalDictionary.Add(o, PlaceholderObject);
>                o.GetHashCode();
>                return true;
>        }
> }
>
> This may modify behaviour of the applications currently using this
> class.
>
> Thoughts?
>
> On Jun 4, 12:07 pm, Lee Henson <[email protected]> wrote:
> > I've created a patch file for the current nh trunk, but I can't see
> > anywhere to upload it to this list. In the meantime, it is available
> > here:
> >
> > http://gist.github.com/123560
> >
> > The patch file includes caching of GetHashCode() values as you
> > suggested, but it has no effect. The act of adding the Child in the
> > Test() method doesn't appear to trigger to a call to it's GetHashCode
> > () (which is what I presume you were expecting to fix the problem,
> > because that would happen before the flush occurred).
> >
> > An alternative example where this would occur is if a user writes
> > their own flush-related event handler and triggers a proxy
> > initialization. Any situation in which a proxy is initialized within
> > AbstractFlushingEventListener.PerformExecutions. Although in this
> > situation I guess you could say "just don't do that".
> >
> > On Jun 3, 10:49 pm, Fabio Maulo <[email protected]> wrote:
> >
> > > here is the problem
> >
> > > unchecked
> > > {
> > > return (Age*397) ^ (Parent != null ? Parent.GetHashCode() : 0);}
> >
> > > The hashCode can't change during instance life time especially when you
> are
> > > using it in a HashTable.
> > > private int requestedHash?
> > > public override int GetHashCode()
> > > {
> > > if(!requestedHash.HasValue)
> > > {
> > >       unchecked
> > >       {
> > >         requestedHash = (Age*397) ^ (Parent != null ?
> Parent.GetHashCode() :
> > > 0);
> > >       }}
> >
> > > return requestedHash;
> >
> > > }
> >
> > > 2009/6/3 Lee Henson <[email protected]>
> >
> > > > I have a test case that contains the following scenario:
> >
> > > > Parent has a custom generic set of Child which is empty
> > > > Parent has an association to a MedicalRecord
> > > > Doctor has an association to the same MedicalRecord
> > > > MedicalRecord has an set of Disease which is empty
> >
> > > > In a new session:
> >
> > > > I load the Doctor, which has the side-effect of creating a proxy of
> > > > MedicalRecord
> > > > I call a method on my Parent.Child custom collection which adds a
> > > > Child item
> > > > I save the Parent
> >
> > > > Within the flush machinery, my Child gets placed in a Hashtable
> > > > (PersistentSet.GetSnapshot()) which causes an evaluation of
> GetHashCode
> > > > (). Since my Child.GetHashCode has a dependency on the
> > > > Parent.GetHashCode it calls that too, and that in turn calls
> > > > MedicalRecord.GetHashCode. At this point, because MedicalRecord
> > > > already exists in the session as a proxy, it attempts to initialize
> > > > the proxy. This causes the Diseases collection to be added to the
> > > > session, and before you know it:
> >
> > > > AssertionFailure - collection was not processed by flush
> >
> > > > It might be a bit of a contrived example, but in my real model which
> > > > is a tad more complicated I am seeing this error. Rather than paste
> > > > all the code in this message, you can view the test case files/
> > > > mappings here:
> >
> > > >
> http://github.com/leemhenson/nhibernate/commit/4728a32efa48dc836441d3...
> >
> > > > There are a couple of other jira issues logged in this area for
> java's
> > > > hibernate:
> >
> > > >
> http://opensource.atlassian.com/projects/hibernate/browse/HHH-2763;js...
> >
> > > >
> http://opensource.atlassian.com/projects/hibernate/browse/HHH-3225;js...
> > > >http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-178
> >
> > > > Thoughts?
> >
> > > > Cheers
> > > > Lee
> >
> > > --
> > > Fabio Maulo
> >
>


-- 
Fabio Maulo

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to