Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HIbernate loads subclasses along with classes

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?

like image 403
rima Avatar asked Aug 05 '10 08:08

rima


2 Answers

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 like DomesticCat. 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 using Query.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 default polymorphism="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 {
    ...
}
like image 149
Pascal Thivent Avatar answered Oct 24 '22 17:10

Pascal Thivent


Assume you have a class structure as follows:

class Animal { }

class Dog : Animal { }

class Cat : Animal { }

then when you select all Animals, you'd expect to also load all Dogs and Cats. After all they are Animals.

A different story are the associations. You can created you mappings such that the associations are lazy load instead of eager load.

like image 21
Manfred Avatar answered Oct 24 '22 19:10

Manfred