Search code examples
javahibernatesingle-table-inheritance

Nested Single Table Inheritance


I'm facing an issue with an object model and Hibernate. I would like the entire model to be stored as a single table.

I have tried the the following, but when I ask Hibernate to generate the SQL create files, it creates 3 tables instead of only 1. The class hierarchy might seem odd, but it is taken out of context of course :)

Attempt 1:

@MappedSuperclass
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "CATEGORY", discriminatorType = DiscriminatorType.STRING, length  = 10)
@Table(name = "the_table")
public abstract class A {}

@MappedSuperclass
@DiscriminatorValue(value = "B")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 20)
public abstract class B extends A {}

@Entity
@DiscriminatorValue(value = "X")
public class X extends B {}

@Entity
@DiscriminatorValue(value = "Y")
public class Y extends B {}

@Entity
@DiscriminatorValue(value = "Z")
public class Z extends B {}

Attempt 2: We are getting there, not it creates 1 table, but there is no discriminator column generated. Can anybody spot the error?

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "CATEGORY", discriminatorType = DiscriminatorType.STRING, length  = 10)
@DiscriminatorFormula(value = "CATEGORY || '_' || TYPE")
@Table(name = "the_table")
public abstract class A {}

@Entity
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 20)
public abstract class B extends A {}

@Entity
@DiscriminatorValue(value = "B_X")
public class X extends B {}

@Entity
@DiscriminatorValue(value = "B_Y")
public class Y extends B {}

@Entity
@DiscriminatorValue(value = "B_Z")
public class Z extends B {}

Solution

  • Remove @MappedSuperclass and try. Also you can't have @Inheritance tag twice in a single hierarchy - only one will be used.

    If you want to use multiple columns as discriminator use the @DiscriminatorFormula

    @Entity
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorForumula("CATEGORY || '_' || TYPE")
    public abstract class A 
    
    @Entity
    @DiscriminatorValue(value = "B_X")
    public class X extends A {}
    
    @Entity
    @DiscriminatorValue(value = "B_Y")
    public class Y extends A {}
    
    @Entity
    @DiscriminatorValue(value = "B_Z")
    public class Z extends A {}