views:

44

answers:

3

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?

A: 

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).

Zenzen
Polymorphic queries just occurs, the various inheritance strategy just provide good or poor support for it. My point is that changing the inheritance strategy won't disable polymorphic queries.
Pascal Thivent
+2  A: 

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.

John
Thanks John.I got your point. can you let me know what to specify in the mapping file so that the association is loaded ,only when it is required through fetchmode.The problem i am facing currently is that, when i am loading the superclass,it is also loading the associations of the subclass.I want to avoid doing that
rima
For lazy loading of one-to-one, see:http://community.jboss.org/wiki/Someexplanationsonlazyloadingone-to-oneorhttp://stackoverflow.com/questions/389026/nhibernate-how-to-enable-lazy-loading-on-one-to-one-mappingFor lazy loading of one-to-many, seehttp://nhforge.org/doc/nh/en/index.html#collections-lazy
John
This would work for associations (has-a relations). Would it work for Polymorphic queries (is-a) also?
Reddy
+1  A: 

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 {
    ...
}
Pascal Thivent