Ah - thanks. The light bulb was a little dim today... :) Symon.
On Tue, Dec 16, 2008 at 8:14 PM, Gustavo Ringel <[email protected]>wrote: > I figure Entity And Hash Code Provider in AA (Ayende's Acronyms) > > Gustavo. > > > On Tue, Dec 16, 2008 at 9:12 PM, Symon Rottem <[email protected]> wrote: > >> Excuse my ignorance, but what's EAHCP? >> >> Agreed, the second issue won't happen if you remain in the context of a >> session, but this bit me when I was working with a non-web app and had >> entities that had a lifetime in memory between sessions. I only made the >> point because I was bitten and figure it's worth others knowing about. >> >> Cheers, >> >> Symon. >> >> >> On Tue, Dec 16, 2008 at 3:45 PM, Ayende Rahien <[email protected]> wrote: >> >>> >>> >>> On Tue, Dec 16, 2008 at 5: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... >>>> >>>> This doesn't happen in practice. Because it is Cat that inherit from >>> EAHCP. >>> >>> >>> >>>> >>>> >>>> 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. >>>> >>>> This approach assume that you are using an entity in the context of a >>> session. If you try to mix things, it is on your head to make sure >>> everything works. >>> >>> >>>> 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 Rottem >>>> http://blog.symbiotic-development.com >>>> >>>> >>>> >>>> >>> >>> >>> >> >> >> -- >> Symon Rottem >> http://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 -~----------~----~----~----~------~----~------~--~---
