10

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.

2
  • 3
    Very good question indeed! I am afraid you are stuck to the SQL CASE solution. Something like a forceDefault=true option (map to root class instead of exception) for the @DiscriminatorColumn or @DiscriminatorFormula annotation would be nice to have. Is the @DiscriminatorValue on the root class also missing in your working code or just in the example? If no, maybe you can force the default mapping this way. Cannot try it out right now but I doubt it, if @DiscriminatorColumn is used a default value is generated for a missing @DiscriminatorValue. Commented Jun 30, 2012 at 12:00
  • @DiscriminatorValue has been missing in the code and in the example, too. And this little detail persuaded me to dig into the Hibernate code once again and find the solution. See bellow. Commented Jul 2, 2012 at 10:34

2 Answers 2

9

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() { ... }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Very nice! Can you provide a link where this is documented or is it only documented in the code?
I have found it in the code, see the class SingleTableEntityPersister. You can find some sources by Google search. Otherwise I cannot find it the official docs.
5

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.