Single Table

The first approach will only use one table. From the class diagram below you can see that a plant has some fields and that each subclass adds a field, for example flower adds the color. This results can be found in one big table holding all the fields. The disadvantage of this approach is that fields in the subclasses Tree and Flower must accept null values. A flower will not set the field has_fruits. So has_fruits must allow null values. Full source code is provided in the package: de.laliluna.inheritance.singletable

Single table inheritance

Hibernate distinguishes the different classes using a discriminator column. When the column type contains KitchenMouse then the row will be treated as KitchenMouse.

Annotation mapping. 

import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
.......... snip .......
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public class Mouse {
    @Id @GeneratedValue
    private Integer id;
    private String name;

The LibraryMouse and KitchenMouse class are fairly simple. They inherit from Mouse and add only their specific attributes.

public class KitchenMouse extends Mouse{

    private String favouriteCheese;

Optionally you can define a different discriminator value. By default the class name is used.

public class LibraryMouse extends Mouse{

    private String favouriteBook;

Other classes can have relations to the subclass (Flower) as well as to the parent class (Plant).

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
........ snip ........
public class House implements Serializable {
.... snip .....
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "garden_plant_id")
    private Set<Mouse> allMice = new HashSet<Mouse>();

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "garden_flower_id")
    private Set<KitchenMouse> kitchenMice = new HashSet<KitchenMouse>();

Required Is set in the parent class Defines the inheritance strategy.
Optional Is set in the parent class Can be used to explicitly specify a discriminator column
Optional Can be set in the parent and subclasses Can be used to explicitly define what is written into the discriminator column for the specific class.
DiscriminatorType.CHAR | .INTEGER | .STRING
Optional Is set in the parent class Is part of the discriminator column definition. Defines which type the discriminator column has.

XML mapping. 

<hibernate-mapping package="de.laliluna.inheritance.singletable" >
  <class name="Mouse" >
......... snip .......
    <discriminator column="plant_type" type="string"></discriminator>
    <subclass name="KitchenMouse" discriminator-value="KitchenMouse">
      <property name="favouriteCheese" />
    <subclass name="LibraryMouse"  discriminator-value="LibraryMouse">
      <property name="favouriteBook"/>

Other classes can have relations to the subclass (KitchenMouse) as well as to the parent class (Mouse).

<hibernate-mapping package="de.laliluna.inheritance.singletable" >
  <class name="House" >
...... snip ........
    <set name="allMice"  table="house_mouse">
      <key column="house_id"></key>
      <many-to-many class="Mouse">
       <column name="mouse_id"></column>

    <set name="kitchenMice" table="house_kitchen_mice" >
      <key column="house_id"></key>
      <many-to-many class="KitchenMouse">
       <column name="kitchen_mouse_id"></column>

Samples of use:

/* create and set relation */
House house = new House();
Mouse bea = new Mouse("Bea");
KitchenMouse john = new KitchenMouse("John");
LibraryMouse tim = new LibraryMouse("Tim");

/* get all kind of mice*/
List<Mouse> result = session.createQuery("select m from Mouse m")

/* select all kitchen mice who like Gauda cheese blue flowers */
List<KitchenMouse result = session
   .createQuery("select m from KitchenMouse m where m.favouriteCheese ='Gauda'")

/* select all mice of type LibraryMouse */
List<LibraryMouse> result = session
   .createQuery("select m from Mouse m where type(m) = LibraryMouse ")