Search code examples
hibernatejpasingle-table-inheritancediscriminator

JPA (Hibernate) SINGLE_TABLE inheritance catch-all discriminator value?


I am mapping a legacy database, one table of which maps naturally to an inheritance hierarchy using the SINGLE_TABLE mapping using a discriminator column. The problem is that there are a huge number of discriminator values! (Also, new ones are occasionally added and the app should automatically pick them up in polymorphic queries). From the point of view of my app, I would like to treat the vast majority of these different types identically (i.e., just map them to the base class in the inheritance hierarchy). However, for a handful, I would like to map to a specific sub-class. The problem is that JPA seems to require that I provide a single specific @DiscriminatorValue on the base class (or otherwise it generates a default one).

To be concrete:

@Entity
@Table("products")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "product_type")
@DiscriminatorValue( *anything not specified elsewhere!* )
public class Product {
    ...
    public double calculateMarkup() { ... default impl ... }
}
@Entity
@DiscriminatorValue("ProductA")
public class ProductA extends Product {
    ...
    @Override public double calculateMarkup() { ... specific impl ... }
}

Is there any way to map this elegantly in JPA (or with Hibernate 3.3-specific extensions)? The only solution I can come with is to abandon inheritance and map the column as a normal field that internally does a switch on that value for the special cases, but that feels unnatural and a little dirty.


Solution

  • Is there any way to map this elegantly in JPA

    No, not that I know of. If the problem is caused on the data layer (i.e. data or database) I'd try to solve it on that layer. Try either of the two below approaches:

    • create a view in the database that is identical to the table except that "anything not specified elsewhere" is mapped* to the default discriminator
    • write an on-insert/update trigger on the Product table that fixes the discriminator values of each reacord*.

    *Oracle for example provides DECODE to map values from range A to range B if-then-else-like.