Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping Hibernate entity for unknown DiscriminatorValue for InheritanceType.SINGLE_TABLE

I have a classic Hibernate @Inheritance(strategy=InheritanceType.SINGLE_TABLE) with @DiscriminatorFormula. It works fine. However, there are about 500 different values for the @DiscriminatorValue in the database and I need map just about 30 of them to Java classes (children) and the rest of them to map to the parent Java class.

The problem can be modelled as an example inheritance on Animal class.

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula("...")
public class Animal implements Serializable {
  ...
  @Column
  public String getName() { ... }
}

So I have have about 30 subclasses of Animal defined in the Java code with @DiscriminatorValue. When Hibernate founds unknown value for the discriminator, then it throws WrongClassException. However, I need to map these unknown discriminator values to one entity, the best it the Animal class. (I need to use only the method getName() in such cases.)

I know one solution is to put a SQL CASE into the @DiscriminatorFormula but then I have to state there all 30 known discriminator values (plus more when I will need to add others). So I am looking for more flexible solution.

P.S. It is a legacy code, so I cannot change the model.

like image 754
xmedeko Avatar asked Jun 30 '12 08:06

xmedeko


2 Answers

tscho has pointed me in the right direction, so I was able to find a solution for my case. The @DiscriminatorValue evaluates special values @DiscriminatorValue("null") and @DiscriminatorValue("not null"). The second one is the right for me.

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula("...")
@DiscriminatorValue("not null")
public class Animal implements Serializable {
  ...
  @Column
  public String getName() { ... }
}
like image 98
xmedeko Avatar answered Sep 18 '22 15:09

xmedeko


Good news. I have just documented this behavior in the new User Guide. This is the JIRA issue.

Basically, you have two options:

  • @DiscriminatorValue("not null") as a fall-back strategy when there is no explicit discriminator value mapping matching the underlying database column value.
  • @DiscriminatorValue("null") for when the database column value is null. Usually, you'd use this for the base class.

There's a detailed example on the Hibernate blog as well.

like image 26
Vlad Mihalcea Avatar answered Sep 19 '22 15:09

Vlad Mihalcea