Becuase the hashcode is generated from the lifetime id and would change if
you based it on the database allocated id at some point later.  Since the
entity could still be in memory there's a chance that the hashcode could
change which would break the hashcode contract and possibly allow you to add
the same entity to a hash table more than once.

Symon.

On Tue, Dec 16, 2008 at 2:33 PM, epitka <[email protected]> wrote:

>
> I interested in why you have to persist LifetimeId. Could you not use
> a lifetimeid only if instance does not have a "recordId"?
>
> On Dec 16, 4:29 am, "Symon Rottem" <[email protected]> wrote:
> > There are a couple of problems with this approach - it's pretty good, but
> I
> > it's still got a couple of holes.
> >
> > There are a couple of issues:
> >
> > 1.  The cast in the equals method will not necessarily result in the type
> > you're expecting:
> >
> > T other = obj as T;
> >
> > If the current instance is a DomesticCat and the passed instance is a Cat
> > proxy that, in fact, represents a DomesticCat instance then the cast
> would
> > fail and return null because the Cat proxy cannot be cast to DomesticCat.
> > This could be worked around using the NHibernateUtils.GetClass(entity)
> > method, but that might cause performance issues since the DB would need
> to
> > be hit for proxies...
> >
> > 2.  This approach will still break if you have a transient entity that
> you
> > persist then evict from the Session thereby making it disconnected then
> > compare it with another loaded copy of same entity; the loaded entity and
> > the disconnected entity will be seen as equal but will have different
> > hashcodes breaking the contract which indicates that if equals() returns
> > true then hashcode comparison should also return true.
> >
> > Certainly the approach will work for the majority of circumstances, but
> it's
> > probably worth being aware of the pitfalls just in case you fall into
> them.
> > :)
> >
> > Personally I've worked around the problem by making a base class for my
> > entities that has a read only "lifetime id" property that's allocated a
> GUID
> > value at instantiation and is used for equality and hashcode comparisons.
> > Note that this property is *not* used as the identity map - my entities
> > still have an Id property for that.  The "lifetime id" property is
> persisted
> > and mapped using field access so the read only property can be set when a
> > persisted entity is loaded.
> >
> > In effect, the GUID is generated when the transient instance is
> instantiated
> > and is then persisted with the object; at any point that the persistent
> > entity is reloaded the value is reloaded with it.  If the entity is
> evicted
> > from the session or the session is closed making it a disconnected entity
> > the lifetime id doesn't change.  If the entity is deleted and made
> transient
> > it still remains the same.  You could even re-persist it.
> >
> > Of course, the drawback is that every entity row must now store an
> > additional GUID, however it's not necessary to have an index on this
> column
> > as it will never be searched, so it's not *too* expensive.  You might
> want
> > to make it unique, however, but I don't this it's essential as the
> > likelyhood of having two conflicting GUIDs in memory at the same time
> seems
> > rather low.
> >
> > There may be a better way of handling this, but I haven't found it. :)
> >
> > Cheers,
> >
> > Symon.
> >
> >
> >
> > On Tue, Dec 16, 2008 at 5:33 AM, Ayende Rahien <[email protected]>
> wrote:
> > >http://ayende.com/Blog/archive/2007/06/05/Generic-Entity-Equality.aspx
> >
> > > On Mon, Dec 15, 2008 at 11:32 PM, Tim Barcz <[email protected]>
> wrote:
> >
> > >> I am reading through a book on NHibernate (NHIbernate in Action,
> Manning)
> > >> and when talking about comparing entity values based on database
> identifier
> > >> (which is what EntityBase does) it strongly discourages equality based
> on
> > >> database Id's:
> >
> > >> Unfortunately, this solution has one huge problem: NHibernate doesn't
> > >>> assign identifier values until an
> > >>> entity is saved. So, if the object is added to an ISet before being
> > >>> saved, its hash code changes while it's
> > >>> contained by the ISet, contrary to the contract defined by this
> > >>> collection. In particular, this problem makes
> > >>> cascade save (discussed later in this chapter) useless for sets. We
> > >>> strongly discourage this solution (database
> > >>> identifier equality).
> >
> > >> Generally DDD looks at an Entity's unique ID for determining equality.
> > >> However I'm a bit concerned at the strong warning from the NHibernate
> camp
> > >> about this type of equality comparison.
> >
> > >> What's the thought on this?  I'd be interested in hearing arguments on
> > >> either side.
> >
> > >> Tim
> >
> > --
> > Symon Rottemhttp://blog.symbiotic-development.com
> >
>


-- 
Symon Rottem
http://blog.symbiotic-development.com

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