AnimalDAOImpl

Figure 1. One table per concrete class - DAO implementation for the abstract class
package curam.inheritance;

import java.util.HashSet;
import java.util.Set;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import curam.util.exception.UnimplementedException;

@Singleton
public class AnimalDAOImpl implements AnimalDAO {

  @Inject
  private CatDAO catDAO;

  @Inject
  private DogDAO dogDAO;

  /**
   * Protected no-arg constructor for use only by Guice
   */
  protected AnimalDAOImpl() {
  }

  public Set<Animal> readAllAnimals() {

    final Set<Cat> cats = catDAO.readAllCats();

    final Set<Dog> dogs = dogDAO.readAllDogs();

    final Set<Animal> animals = new HashSet<Animal>(cats.size()
        + dogs.size());
    animals.addAll(cats);
    animals.addAll(dogs);

    return animals;
  }

  public Animal get(final Long id) {
    throw new UnimplementedException();
  }

}

Class declaration

public class AnimalDAOImpl implements AnimalDAO {

The class does not make use of any superclasses for its implementation.

Adapter

Unlike most DAO implementations, there is no adapter variable because there is no physical Animal database table.

DAO instances

@Inject
  private CatDAO catDAO;

  @Inject
  private DogDAO dogDAO;

The class contains injected instances of the DAO interfaces for the concrete classes.

These DAOs will be used to delegate searches to.

Protected constructor

/**
   * Protected no-arg constructor for use only by Guice
   */
  protected AnimalDAOImpl() {
  }

The class contains a protected constructor, as is the norm for DAO implementations.

Performing a search across Animal types

public Set<Animal> readAllAnimals() {

    final Set<Cat> cats = catDAO.readAllCats();

    final Set<Dog> dogs = dogDAO.readAllDogs();

    final Set<Animal> animals =
      new HashSet<Animal>(cats.size() + dogs.size());
    animals.addAll(cats);
    animals.addAll(dogs);

    return animals;
  }

A search of Animal instances across the Cat and Dog tables is performed by naively delegating the searches and combing the results.

Unsupported - retrieval of an Animal by its ID

public Animal get(final Long id) {
    throw new UnimplementedException();
  }
Important: It is not possible to retrieve a generic Animal by its ID. This is because the Cat and Dog database tables maintain their own IDs - there is no concept of an animalID as such.

If you require to be able to retrieve a generic Animal by its ID, then do not choose to store your data using this "One table per concrete class" method.