I am using Hibernate to connect to my database. I have an inheritance structure in my application.The problem is that when i do a query like "from Animal", it does a left outer join for the class Animal,its sub classes and all the associations for Animal and its subclasses. How do i avoid this situation.I want to load the data only when i specify it through a fetchmode in my criteria query?
Basically it's the default ORM inheritance design pattern used by Hibernate called class inheritance (all the classes are mapped to a single table), if you want to change that you can google:
- single class hierarhy or table per class (this will map every class to a separate table in the DB)
- concrete class hierarhy (this will map only the concrete implementations to a table).
Assume you have a class structure as follows:
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
then when you select all Animal
s, you'd expect to also load all Dog
s and Cat
s. After all they are Animal
s.
A different story are the associations. You can created you mappings such that the associations are lazy load instead of eager load.
Yes, Hibernate supports polymorphic queries. From the documentation:
14.8. Polymorphic queries
A query like:
from Cat as cat
returns instances not only of
Cat
, but also of subclasses likeDomesticCat
. Hibernate queries can name any Java class or interface in the from clause. The query will return instances of all persistent classes that extend that class or implement the interface. The following query would return all persistent objects:from java.lang.Object o
The interface
Named
might be implemented by various persistent classes:from Named n, Named m where n.name = m.name
These last two queries will require more than one SQL
SELECT
. This means that the order by clause does not correctly order the whole result set. It also means you cannot call these queries usingQuery.scroll()
.
This is the default behavior (called implicit polymorphism) and Hibernate supports both implicit and explicit polymorphism:
Implicit polymorphism means that instances of the class will be returned by a query that names any superclass or implemented interface or class, and that instances of any subclass of the class will be returned by a query that names the class itself. Explicit polymorphism means that class instances will be returned only by queries that explicitly name that class. Queries that name the class will return only instances of subclasses mapped inside this
<class>
declaration as a<subclass>
or<joined-subclass>
. For most purposes, the defaultpolymorphism="implicit"
is appropriate. Explicit polymorphism is useful when two different classes are mapped to the same table This allows a "lightweight" class that contains a subset of the table columns.
This can be configured at the class level. Use polymorphism="explicit"
if you are if you are using xml mappings, see 5.1.3 Class. Use Hibernate's @Entity
annotation if you're using annotations, see 2.4.1. Entity. Below an example:
@javax.persistence.Entity
@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)
@Inheritance(strategy = InheritanceType.JOINED)
public class Foo {
...
}