getting proxies of the correct type in nhibernate
- by Nir
I have a problem with uninitialized proxies in nhibernate
The Domain Model
Let's say I have two parallel class hierarchies: Animal, Dog, Cat and AnimalOwner, DogOwner, CatOwner where Dog and Cat both inherit from Animal and DogOwner and CatOwner both inherit from AnimalOwner. AnimalOwner has a reference of type Animal called OwnedAnimal.
Here are the classes in the example:
public abstract class Animal
{
// some properties
}
public class Dog : Animal
{
// some more properties
}
public class Cat : Animal
{
// some more properties
}
public class AnimalOwner
{
public virtual Animal OwnedAnimal {get;set;}
// more properties...
}
public class DogOwner : AnimalOwner
{
// even more properties
}
public class CatOwner : AnimalOwner
{
// even more properties
}
The classes have proper nhibernate mapping, all properties are persistent and everything that can be lazy loaded is lazy loaded.
The application business logic only let you to set a Dog in a DogOwner and a Cat in a CatOwner.
The Problem
I have code like this:
public void ProcessDogOwner(DogOwner owner)
{
Dog dog = (Dog)owner.OwnedAnimal;
....
}
This method can be called by many diffrent methods, in most cases the dog is already in memory and everything is ok, but rarely the dog isn't already in memory - in this case I get an nhibernate "uninitialized proxy" but the cast throws an exception because nhibernate genrates a proxy for Animal and not for Dog.
I understand that this is how nhibernate works, but I need to know the type without loading the object - or, more correctly I need the uninitialized proxy to be a proxy of Cat or Dog and not a proxy of Animal.
Constraints
I can't change the domain model, the model is handed to me by another department, I tried to get them to change the model and failed.
The actual model is much more complicated then the example and the classes have many references between them, using eager loading or adding joins to the queries is out of the question for performance reasons.
I have full control of the source code, the hbm mapping and the database schema and I can change them any way I want (as long as I don't change the relationships between the model classes).
I have many methods like the one in the example and I don't want to modify all of them.
Thanks,
Nir