On Jun 4, 1:50 pm, Fabio Maulo <[email protected]> wrote:
> Wait... if the problem was with some proxy the issue is another (probably)
> and was fixed few days ago.

I've scanned the recently fixed jira issues, and there is nothing I
can see that is related to this issue.

> Btw if you have a test you can create JIRA ticket
> attaching the test case.

Opened:

http://nhjira.koah.net/browse/NH-1810

Please use the second attachment (NH1810.patch), it fits with the bug
number naming convention and is a bit tidier than the original patch.

>
> 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