Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate: Is it possible to map multi-level inheritance to single table?

I have following inheritance hierarchy:

Task
  |
SpecificTask
  |
VerySpecificTask

And I'd like to persist it usign single-table inheritance, so I annotated classes:

@Entity
@Table(name="task")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Task 

@Entity
public class SpecificTask extends Task 

@Entity
public class VerySpecificTask extends SpecificTask

When I try to save an object of VerySpecificTask class, I get an error:

Unable to resolve entity name from Class [com.application.task.VerySpecificTask] 
expected instance/subclass of [com.application.task.Task]

What do I wrong? Is it possible to map multi-level inheritance to single table?

EDIT: Here was a lame bug, I've resolved quickly, so I deleted it to not mess this question.

like image 600
mrzasa Avatar asked Feb 03 '12 15:02

mrzasa


People also ask

Which inheritance strategy creates a single table?

In this inheritance strategy, only one table is created for all the classes involved in the hierarchy with an additional column known as a discriminator column.

What are the inheritance mapping strategies in Hibernate?

Hibernate supports the three basic inheritance mapping strategies: table per class hierarchy. table per subclass. table per concrete class.

Why do we use inheritance mapping in Hibernate?

Entity inheritance means that we can use polymorphic queries for retrieving all the subclass entities when querying for a superclass. Since Hibernate is a JPA implementation, it contains all of the above as well as a few Hibernate-specific features related to inheritance.

Which of these inheritance models is not supported by Hibernate?

However, Hibernate does not support mixing <subclass> , <joined-subclass> and <union-subclass> mappings under the same root <class> element.


2 Answers

OK, I've added discriminator column and now it works. Changed code:

@Entity
@Table(name="task")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
        name="DTYPE",
        discriminatorType=DiscriminatorType.STRING
    )

@Entity
public class SpecificTask extends Task 

@Entity
public class VerySpecificTask extends SpecificTask

(I'm adding it just to provide an accepted answer -- I wouldn't resolve it without the helpful comments to the question.)

like image 137
mrzasa Avatar answered Oct 02 '22 17:10

mrzasa


The accepted answer is almost perfect. To make it more clear I want to add a @DiscriminatorValue to each inheritance level.

@Entity
@Table(name="task")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
        name="DTYPE",
        discriminatorType=DiscriminatorType.STRING
)
public class Task

---

@Entity
@DiscriminatorValue(value="DS")
public class SpecificTask extends Task 

---

@Entity
@DiscriminatorValue(value="DV")
public class VerySpecificTask extends SpecificTask

And the materiliazed table looks like

--------------- 
Table: task
---------------
|...|DTYPE|...|
---------------
|...|DS   |...|
|...|DV   |...|
|...|DS   |...|
...
like image 39
Paul Wasilewski Avatar answered Oct 02 '22 15:10

Paul Wasilewski