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