0

I am using Nhibernate and I have a problem when fetching a base class with multiple derived classes (each class mapping a different table). When I watch the request, Nhibernate joins on every derived tables which has a huge an impact on the performances...

Here is a simplified vision of my classes :

public class Animal{
    public virtual int ID { get; set;}
    public virtual string Name { get; set;}
}

public class Dog : Animal{
    //others properties
}

public class Cat: Animal{
    //others properties
}

public class Person{
    public virtual int ID { get; set;}
    public virtual IEnumerable<Animal> Animals { get; set;}
}

A person has a list of Animals and I just want their names. The example is not perfect and more it's more complicated (a banking program) but it reflect well my problematic. I KNOW it can be done differently etc, but it is a legacy so I don't have a choice...

Thanks in advance.

Eric
  • 230
  • 1
  • 2
  • 15
  • 2
    Please post your query where you select the names and mention your inheritance mapping strategy (I assume table per subclass, but with or without a discriminator?). Also, which version of NHibernate are you using? – cremor Nov 29 '12 at 11:40
  • @cremor table per subclass doesnt need a discriminator column. – Firo Nov 29 '12 at 12:56
  • @cremor I am using table per subclass but without a discriminator column and I'm using the version 3.3 – Eric Nov 29 '12 at 13:07
  • @Firo It doesn't need one, but it is possible. See here: http://nhforge.org/doc/nh/en/index.html#inheritance-tablepersubclass-discriminator – cremor Nov 29 '12 at 13:23

2 Answers2

1

IMO NHibernate will only joind tables which contain projected columns. define a query but do not return Person but project into a dto/anonymous class the properties you need

Firo
  • 30,626
  • 4
  • 55
  • 94
  • This Animal class will be referenced in a multitude of others mapped classes (it is on of the main table of the application) so I think your solution is not feasable in my case. – Eric Nov 29 '12 at 13:14
  • @Eric If you need the full Animal class then why shouldn't NHibernate fetch it? It can't fetch Dogs as plain Animals because that would be wrong (assume you have code that checks the type or something like that). Either fetch the full object or only the name string, there is nothing in between. – cremor Nov 29 '12 at 13:27
  • what are you trying to achieve? if you tell NH to load animals it has to join he other tables to know which Subtype it has to create. If you knwo you only need the name when referenced from other entities then map a different animal which is not in this hierarchy and reference that from all other entities – Firo Nov 29 '12 at 13:28
  • Animal is not an abstract type, it contains lots of infos which are suffisiant in most of my queries, so their is no reason for Nhibernate to load the derived class in my case – Eric Nov 29 '12 at 13:33
  • @Eric see my last comment. The runtime Type is important because there could be polymorphismn, typechecks, casting and the like which will all fail. So NH does the only right thing and joins the other tables – Firo Nov 29 '12 at 13:41
1

After all, I created a class AnimalBase which is inherited by Dog, Cat and so forth and a class Animal without any child (both having the interface IAnimal).

As in 95% of my request, I only need Animal, I reference this class in my other objects like Person.

Not perfect but I did not find anything better...

Thanks Firo for your help.

Eric
  • 230
  • 1
  • 2
  • 15