﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Alex Yakunin commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>&gt; I switched to simple many-to-ones, where Animal would have Dog and Cat properties, and I've never been happier!
  
  
In some cases this is possible (and likely, desirable), although in general such a design won't work. I.e. it is a solution working in particular cases.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment33</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment33</guid><pubDate>Sat, 05 Sep 2009 06:02:53 GMT</pubDate></item><item><title>Mats Helander commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>&gt;I switched to simple many-to-ones, where Animal would have Dog and Cat properties, and I've never been happier!
  
  
"Mr_Simple approves of your coding style!"
  
  
Same here.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment32</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment32</guid><pubDate>Fri, 04 Sep 2009 16:34:56 GMT</pubDate></item><item><title>Alex Yakunin commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>And... I also surprised to hear this: "However, NH says that entities SHOULD implement Equals, GetHashCode &amp; Equality operators, because of that exact reason.".
  
  
I'm curious, what is the typical implementation? I.e. 2 things are clear for me:
  
- Such instances are frequently used in sets &amp; dictionaries
  
- Thus their hash code shouldn't change
  
- Likely, two instances with the same key must be equal
  
  
Thus I see the only good implementation of these methods: they must rely only on key comparison &amp; key hash code.
  
  
If there will be anything else, you'll get mutable GetHashCode = forget about dictionaries.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment31</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment31</guid><pubDate>Thu, 03 Sep 2009 11:32:38 GMT</pubDate></item><item><title>Alex Yakunin commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Just read this post (after reading &amp; commenting a subsequent one about the same). I'm fully agree, such a practice is quite bad.
  
  
Moreover, this is completely contradictorily to Liskov principal (in fact, you're talking about inverse principal at all!): this principal does not imply you must expose absolutely the same logic as in base type. It implies any subclass instance can replace superclass instance everywhere. But you're doing COMPLETELY INVERSE THING! 
  
  
Do you understand that such imagination of Liskov substitution principal makes polymorphism impossible at all?
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment30</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment30</guid><pubDate>Thu, 03 Sep 2009 11:21:44 GMT</pubDate></item><item><title>Roger Alsing commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>@Frank
  
  
Its way to easy to say "use polymorphism instead of conditionals and every problem will go away"
  
  
It does solve some problems, yes..
  
  
But what if you pass the object to some custom serializer?
  
What if you place it in a hashtable?
  
  
Also, never forget that people are people and will most likely do the most quick n dirty solution they can come up with.
  
  
And don't get me wrong, Im not trying to bash NHibernate or anything.
  
I'm just saying that O/R mapping is hard enough any way for most people.
  
So adding extra friction in terms of object comparison and identity problems will not make it easier for anyone.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment29</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment29</guid><pubDate>Thu, 03 Sep 2009 07:03:49 GMT</pubDate></item><item><title>Frank commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>How much of a real problem is it?
  
  
Unfortunately at my current company, we engage in anemic models, and to make it even more problematic, data sets with a custom written data layer for each system. And open source libraries like NHibernate are a no-go, because too many people think they need to be in full control of everything and open source is not to be trusted.
  
  
But back to the question. In my very limited experience with models, I don't see why one would check what the type of the property is. The reason why one uses inheritance is to provide different behavior. Checking for a type looks like behavior at the wrong place. John Chapman seems to be spot on with his example.
  
  
  
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment28</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment28</guid><pubDate>Wed, 02 Sep 2009 21:44:36 GMT</pubDate></item><item><title>ivos commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>hey, if you have an animal, you don't have a cat or a dog. you have an animal. you shouldn't make any decision based on the type. Instead, you should use a polymorphic solution (like the one John said, a Visitor, etc). And what about overriding methods with "new"?!!? I think all this problems will be solved once the people that uses ORMs understands the O.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment27</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment27</guid><pubDate>Wed, 02 Sep 2009 20:56:46 GMT</pubDate></item><item><title>Fabio Maulo commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Guessing that a Cat can't be a lover of a Dog I would imagine a different implementation.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment26</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment26</guid><pubDate>Wed, 02 Sep 2009 19:34:46 GMT</pubDate></item><item><title>gunteman commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Oh,you mean the "is" check? I agree about that one, but I fail to see how Anders' (not Richard's) statement has anything to do with that. 
  
  
NHibernate has made a conscious decision in this matter. It serves a very real and valuable purpose. Doesn't make it "the right" decision though.  
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment25</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment25</guid><pubDate>Wed, 02 Sep 2009 18:43:04 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>See Replace conditional with polymorphism.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment24</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment24</guid><pubDate>Wed, 02 Sep 2009 18:09:21 GMT</pubDate></item><item><title>gunteman commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>"And you code still violate Liskov "
  
  
Why? How?
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment23</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment23</guid><pubDate>Wed, 02 Sep 2009 18:07:04 GMT</pubDate></item><item><title>Mr_Simple commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>@Tyler
  
  
&gt;I switched to simple many-to-ones, where Animal would have Dog and Cat properties, and I've never been happier!
  
  
Mr_Simple approves of your coding style!
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment22</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment22</guid><pubDate>Wed, 02 Sep 2009 15:43:25 GMT</pubDate></item><item><title>Tyler Burd commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>This is why I stopped using inheritance with NH a year ago.  I tried using the interface proxies to get around the issues, but it never felt right having to create interfaces for my persistent classes and remember to use them only within an inheritance hierarchy.  I switched to simple many-to-ones, where Animal would have Dog and Cat properties, and I've never been happier!  The team understands what's going on, they can change the type of animal from cat to dog, and they don't get any of these "is it or isn't it a dog?!" issues.
  
  
I think the inheritance is very well done in NH, I just don't like having to consider so many special cases.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment21</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment21</guid><pubDate>Wed, 02 Sep 2009 15:21:09 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Roger,
  
Yep, leaky this is a real and annoying issue.
  
We run around this a few times trying to resolve that, but there isn't a good solution that doesn't kill the general case for the special case.
  
  
However, NH says that entities SHOULD implement Equals, GetHashCode &amp; Equality operators, because of that exact reason.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment20</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment20</guid><pubDate>Wed, 02 Sep 2009 14:26:59 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Roger,
  
Nope, you can't do that without hitting the actual table container the data. That affect the general case vs. the special case.
  
And you code still violate Liskov
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment19</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment19</guid><pubDate>Wed, 02 Sep 2009 14:25:05 GMT</pubDate></item><item><title>kork commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>roger hibernate works with the concept of entity and 2 entity can be compared only by their id, so in your example you must compare using 
  
lover1.Animal.Id  == lover2.Animal.Id or redefine Equals and the == operator to works using only the Id.
  
  
conceptually the choise it's the better choise available
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment18</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment18</guid><pubDate>Wed, 02 Sep 2009 14:04:48 GMT</pubDate></item><item><title>Roger Alsing commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>hehe, I'll bite even more on this.
  
  
This introduces what we called "Leaky this" problem.
  
  
The actual animal instance and the ghost proxy that is assigned to the Animal property will not be the same instance.
  
As you explained, the ghost proxy will delegate any call to the real instance.
  
  
So if the Animal class would contain a method called "SetMeAsFavoriteAnimal(AnimalLover lover)"
  
  
e.g.
  
void SetMeAsFavoriteAnimal(AnimalLover lover)
  
{
  
    lover.Animal = this;
  
}
  
  
then consider the following code:
  
  
AnimalLover lover1 = LoverRepo.GetLoverById(1);
  
AnimalLover lover2 = new AnimalLover();
  
  
lover1.Animal.SetMeAsFavoriteAnimal(lover2);
  
  
if (lover1.Animal == lover2.Animal)
  
   //THIS WILL NOT EXECUTE!!!
  
  
Because lover1.Animal is a ghost proxy and lover2.Animal is a real animal instance.
  
  
And this kind of problems are a PAIN to find.
  
  
I do understand you have chosen this approach from pragmatic reasons, but I think it is conceptually wrong.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment17</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment17</guid><pubDate>Wed, 02 Sep 2009 13:57:54 GMT</pubDate></item><item><title>Roger Alsing commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>That doesnt make the initial statement true.
  
  
&gt;&gt;animalLover.Animal.Id &lt;-- no load
  
  
You could accomplish this using correct proxies also depending on how the mapping is created.
  
If the FK from animal lover to animal contains the type descriminator then you could very well instance a ghost proxy of the correct type.
  
  
Also, assigning objects of the wrong type to an association might be an optimization but it will also enable a bunch of problems.
  
  
And IMO, those problems are more related to Liskov.
  
  
Let's say that you'r setters of the .Animal property contains logic that makes decisions based on the type of the assigned object.
  
  
e.g. 
  
  
set{
  
if (value is dog) 
  
  SendEmailIfDogLacksPuppyVaccination()
  
  
this.animal = value;
  
}
  
  
One can ofcourse argue about how valid that code is, but it does prove that a mapper that uses ghost proxies would break rule of least suprise and that it would potentially break pre/post conditions of your domain logic .
  
  
All of the above is somewhat offtopic, I'm just trying to say that your initial statement is not true and thus you shouldnt emphasise "any"
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment16</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment16</guid><pubDate>Wed, 02 Sep 2009 13:39:20 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Roger,
  
Loading on property access means that you kill a bunch of very important optimizations:
  
  
animalLover.Animal.Id &lt;-- no load
  
  
session.Save(new TreatmentRecord{
  
 Animal = animalLover.Animal &lt;-- no load
  
});
  
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment15</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment15</guid><pubDate>Wed, 02 Sep 2009 13:23:18 GMT</pubDate></item><item><title>Roger Alsing commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>oops.. try = true
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment14</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment14</guid><pubDate>Wed, 02 Sep 2009 13:18:57 GMT</pubDate></item><item><title>Roger Alsing commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>&gt;&gt;Anders,
  
&gt;&gt;Liskov would be rolling in her grave, if she had one 
  
  
What does his statements have to do with Liskov substitution?
  
  
NPersist did load the related entities on property access (when using lazy load that is)
  
  
And thus, we always got an object of the correct type.
  
  
So your statement that this is try for all mappers is simply not correct.
  
  
You eiter lazy load using ghosts, or lazy load on property or field access.
  
  
(And I assume that POCO or not POCO and how to accomplish POCO is out of the scope of this post)
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment13</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment13</guid><pubDate>Wed, 02 Sep 2009 13:18:14 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description> Schrödinger,
  
That is _aweseom_
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment12</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment12</guid><pubDate>Wed, 02 Sep 2009 12:46:00 GMT</pubDate></item><item><title>Schr&amp;#246;dinger commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>no, the cat is dead when you check for it... so it must be dog
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment11</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment11</guid><pubDate>Wed, 02 Sep 2009 12:39:24 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>John,
  
You will get the right behavior, absolutely!
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment10</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment10</guid><pubDate>Wed, 02 Sep 2009 12:33:04 GMT</pubDate></item><item><title>John Chapman commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Ok,
  
  
Let's make this more interesting.  What if the base Animal had a method called ComeHere().  A cat ignores you because cats don't listen, and the dog comes.  Calling that method instead of checking the type, would you get the correct polymorphic behavior?  Assuming that this does behave correctly, you can work around this issue as long as you are aware of it.
  
  
While using NHibernate I never used lazy loaded properties to try to avoid situations like these.  It was perfectly acceptable in our application.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment9</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment9</guid><pubDate>Wed, 02 Sep 2009 12:29:37 GMT</pubDate></item><item><title>Anders Ivner commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Not all valid usage scenarios are classic OO. You may want to use the object for e.g. serialization or data binding using reflection (similar to how NH itself works).
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment8</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment8</guid><pubDate>Wed, 02 Sep 2009 10:54:19 GMT</pubDate></item><item><title>Ayende Rahien commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>Anders,
  
Liskov would be rolling in her grave, if she had one
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment7</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment7</guid><pubDate>Wed, 02 Sep 2009 10:27:21 GMT</pubDate></item><item><title>Anders Ivner commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>This is one of the few (only?) design choices that nHibernate does wrong, imho. Alternately you could:
  
  
1. take the penalty of joining the associated table to determine the actual type of Animal when loading the AnimalLover.
  
2. Let the AnimalLover lazy load the animal when accessing the Animal property.
  
  
Alas, nhibernate sacrifices correctness for performance.
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment6</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment6</guid><pubDate>Wed, 02 Sep 2009 09:02:25 GMT</pubDate></item><item><title>Steve Powell commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>oops. Should have been Cat.LivesIn not Cath.LivesIn. Not sure how the wife managed to creep into my comment there....
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment5</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment5</guid><pubDate>Wed, 02 Sep 2009 08:25:58 GMT</pubDate></item><item><title>Steve Powell commented on Challenge: The lazy loaded inheritance many to one association OR/M conundrum</title><description>This has been the only real problem we have been having with nHibernate. 
  
We have a parallel class hierarchy problem where we have Animal, Cat, Dog and AnimalHome, Kennel, CatBasket.  Animal has a property LivesIn which is of type AnimalHome and Dog and Cat override this property with the 'new' keyword returning Kennel and CatBasket.  If you try and go Cath.LivesIn you get a cast exception.  
  
We have found a work around if anyone wants to know it..... but it aint pretty!
</description><link>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment4</link><guid>http://ayende.com/4165/challenge-the-lazy-loaded-inheritance-many-to-one-association-or-m-conundrum#comment4</guid><pubDate>Wed, 02 Sep 2009 08:24:02 GMT</pubDate></item></channel></rss>