Hibernate inheritance: Discriminator Column vs Formula

Java allows you to take advantage of the domain model and think in terms of objects to elaborate technical solutions to real world problems like transferring money, buying products online and so on. These domain objects are expected to be stored and retrieved from a database, but storing the domain objects into a relational database is not so straightforward. The object-relational paradigm is mismatching, because the objects in our application are no table in a row-column format.
Hibernate allows to handle the object-relational mismatch through ihneritance strategies. The default one is the single table strategy. To achieve it you need to use discriminators.
You might add discriminator columns, but most times it´s not a good choice, especially for legacy systems, because it takes an extra column (called “d_type” as default name). So you might consider better solutions, like using the discriminator formula instead.

DiscriminatorFormula is an alternative to DiscriminatorColumn.
With DiscriminatorColumn it creates an additional column (as default called “dtype”) which contains the discriminator value.
You put the annotation in the superclass, (which maps the real table as default):

    @Entity
    @Table(name = "features")
    @DiscriminatorColumn
     public class Features{
    //valid code
    }

DiscriminatorFormula allows you to check the database row content and “select” a subclass by the discriminator value. No additional (“dtype”) column is created.
In the main class you annotate the superclass with the formula, like:

    @Entity
    @Table(name = "features")
    @DiscriminatorFormula(
    		"CASE WHEN num_value IS NOT NULL THEN 'NUMERIC' " +
	   		" WHEN txt_value IS NOT NULL THEN 'TEXT' end")
     }
     public class Features{
    //valid code
    }

In the DiscriminatorFormula you just put some pure SQL to do what you need.

You can choose one of these two options and the subclasses is exactly the same in both cases.
the subclasses are annotated java object (with @Entity), but no real table, they are just useful to map columns in the table represented by the main class.
In the subclasses you specify the discriminator value, for Example:

    @Entity
    @DiscriminatorValue('NUMERIC')
    public class NumericFeatures extends Features{

    private Double numValue;

	public Double getNumValue() {
		return numValue;
	}

	public void setNumValue(Double numValue) {
		this.numValue = numValue;
	}
   //valid code

}

In the table called “features” you have both columns “num_value” and “txt_value”, containing the corrensponding values.
With DiscriminatorColumn you would have either “NUMERIC” or “TEXT” value in the dtype column and also both the “num_value” and “txt_value” columns.

If you don´t specify the inheritance strategy the default is “SINGLE_TABLE”. the following annotation can be omitted if it´s your chosen strategy:

     @Inheritance(strategy = InheritanceType.SINGLE_TABLE)

With or without this annotation you get one table called “Features”.