Hey all,
I have a scenario where I have 3 tables that have the same parent object (TABLE_PER_CLASS), but the performance is very slow.
Tested both hibernate 3.6.1 and 4.1.7 with MS SQL 2005, sun jdk6.
Code:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Animal
String animalCount;
....
@Entity
public class Duck extends Animal{
....
@Entity
public class Goose extends Animal{
....
@Entity
public class Chicken extends Animal{
....
Each of the individual objects map to their own table, but the primary key is unique spanning all 3 (if a PK of '12345' exists in any one table, it does not exist in the others). There is no 'animal' table itself, such as the above there are three tables.
To be clear - a farm will only have zero or one 'goose' object, one 'chicken' object, one 'duck' object for the scenario I'm testing, but an unknown number of different types of animals. Although I think the many of the same objects should also work, I'm focusing on current scenario.
When I have a named query for a Farm entity that contains many animals.
Code:
@Entity
public class Farm
...
private List<Animal> animals;
@OneToMany(fetch=FetchType.LAZY, targetEntity=Animal.class)
@JoinColumn(name="farmId", referencedColumnName="farmId", insertable=false, updatable=false)
@BatchSize(size=3)//hibernate-specific performance optimization, no difference if in or not.
public List<Animal> getAnimals() {
return this.animals;
}
The problem: named query "select farm from Farm farm join fetch farm.animals ....(other join fetch non-inheritance)... where farmid=:farmid"When I have many farms (>100) and each farm has several animals (0-3) I'm running into some serious performance problems.
1) setMaxResult is *not respected* unless I remove the join fetch on the inheritance animals. So it always returns all farms and all animals (in my scenario,
hibernate 3.6.1 was 33 seconds, hibernate 4.7.1 was 18 seconds for 308 farms)
2) removing the animals inheritance in the join-fetch (while having 5 other 'non-inheritance' objects) allows setMaxResults to properly 'top' in MS SQL, as well as speeds of 150ms for 100 paginated results (and 300ms for all 308, to compare to above 33sec and 18 sec). The raw query time was insignificant.
3) the raw query (using show_sql) directly through the database is very fast even with the join fetch to the inheritance animals (worst case scenario) and was only
225ms (total result of 655 records for the 308 farms). the 655 results was from the join to the (Select... union all select ...) for the individual animal tables.
I could get by with 'all', but something significantly increases the 'all results' time from 300ms for Farm with other objects and no animals, to 18 seconds (33 seconds older version) when including animal objects.
question: is this expected behavior when using TABLE_PER_CLASS inheritance, and what are some options to resolve the performance problems (while still trying to stay as close to JPA if possible).
thanks!
-Darren