Inheritance Strategies in Hibernate 4.3

Hibernate uses following strategies for saving an inheritance hierarchy of classes created in Java to the databases: SINGLE_TABLE, TABLE_PER_CLASS and JOINED.  

We can use @Inheritance annotation over the entity class to specify the inheritance strategy.

We specify the inheritance strategy by assigning a strategy from the InheritanceType enumeration to the strategy parameter of the @Inheritance annotation.  

Strategies defined in the InheritanceType enumeration are InheritanceType.SINGLE_TABLE, InheritanceType.TABLE_PER_CLASS and InheritanceType.JOINED.

If you don’t provide the @Inheritance annotation or any strategies, the default strategy is SINGLE_TABLE.

Please note that the level of normalization needed might be different from a case to case basis depending on the complexity of your application. Otherwise there would not have been three different strategies, but only one. Please check with your database expert or see the notes on database under the extras section here for finding the right one for you.

 

SINGLE_TABLE strategy

  • In the SINGLE_TABLE strategy, hibernate will create a single table for all the classes in an inheritance hierarchy.

  • There will be a discriminator column that tells us the class to which that row belongs.

  • Problems with single table are that

    • it is the least normalized and

    • columns for all classes in the inheritance hierarchy will be present in the table, even if it is not used by other classes.

  • Example: Consider the example of three entity classes – Shape, Rectangle and Circle; where Rectangle and Circle extends from Shape. With SINGLE_TABLE strategy, circle will also have length and breadth columns, though not used; and Rectangle will have the radius field. 

 

TABLE_PER_CLASS strategy

  • In the TABLE_PER_CLASS strategy, hibernate will create a separate table for all the classes in an inheritance hierarchy.

  • All the columns that you receive as part of inheritance will be part of the final class.

  • This is better than single table strategy that you will only have columns of your class.

  • However it is still not normalized completely as inherited columns are repeated in all tables.

  • For instance, Fields inherited from Shape such as id and fillcolor are repeated in all the tables.

  • With some databases such as MySQL, you need to use the annotation @GeneratedValue(strategy=GenerationType.TABLE) on the the auto generated id field.

    • With other databases, just @GeneratedValue as in SINGLE_TABLE strategy might just work.

  • @GeneratedValue annotation considerations in TABLE_PER_CLASS strategy are:

    • @GeneratedValue is used for primary key generation.

    • We can specify a strategy for primary key generation using the enumeration GenerationType.

    • GenerationType defines the types of primary key generation and can have values AUTO, IDENTITY, SEQUENCE and TABLE.

      • AUTO indicates that the persistence provider should pick an appropriate strategy for the particular database.

      • IDENTITY indicates that the persistence provider must assign primary keys for the entity using database identity column.

      • SEQUENCE indicates that the persistence provider must assign primary keys for the entity using database sequence column.

      • TABLE indicates that the persistence provider must assign primary keys for the entity using an underlying database table to ensure uniqueness.

    • Usually @GeneratedValue ,which is same as @GeneratedValue( strategy = GenerationType.AUTO), can be used for any id generation.

      • However there might be some exceptions or limitations for some jpa provider with some databases with respect to the default behavior.

        • In that case, it is better to use a specific type than AUTO.

          • For instance, In table per class strategy, if you use AUTO with MySQL when using hibernate 4.3, you will get an exception org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for:…

          • You can resolve this by using GenerationType.TABLE as: @Id @GeneratedValue(strategy=GenerationType.TABLE)

        • If the database that you use has problems with AUTO, try using TABLE for TABLE_PER_STRATEGY.

          • Else just play with GenerationType and find the right one. 

  • @DiscriminatorValue and @DiscriminatorColumn annotations should be used with SINGLE_TABLE strategy as discriminator column is only present in SINGLE_TABLE strategy.

    • There is no special use if you use them with other strategies,

      • however you will not see any error if you still have them (tested with hibernate4.3).

 

JOINED strategy

  • In the JOINED strategy, hibernate will create a separate table for all the classes in an inheritance hierarchy, and the tables are also normalized.

  • Columns that you receive as part of inheritance will be part of parent class and referred from subclass tables using a foreign key.

    • In a TABLE_PER_CLASS strategy, all these columns were present in all the tables and there were no foreign key references.

  • This is the most normalized inheritance strategy.

  • Example: Shape contains id and fillcolor. Rectangle or Circle will not have fillcolor, but will have a shapeid column that references the shapeid column of the Shape table. 

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!