Inheritance
Relational tables know nothing about inheritance, but Java classes often form hierarchies. Suppose posts in the blog can have media attached: images with a width and height, and videos with a duration. Both are "media" with a title. Hibernate can store such a hierarchy in several ways — they are called inheritance strategies.
The hierarchy
// src/main/java/com/example/blog/Media.java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Media {
@Id
@GeneratedValue
private Long id;
private String title;
protected Media() {
}
protected Media(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public abstract String describe();
}// src/main/java/com/example/blog/Image.java
@Entity
public class Image extends Media {
private int width;
private int height;
protected Image() {
}
public Image(String title, int width, int height) {
super(title);
this.width = width;
this.height = height;
}
@Override
public String describe() {
return "image " + width + "x" + height;
}
}Video is written the same way, with an int seconds field. All three classes are listed in persistence.xml.
A polymorphic query
// src/main/java/com/example/blog/Main.java
emf.runInTransaction(em -> {
em.persist(new Image("Cover", 1200, 630));
em.persist(new Video("Demo", 95));
});
List<Media> media = emf.callInTransaction(em ->
em.createQuery("select m from Media m order by m.id", Media.class).getResultList());
for (Media m : media) {
IO.println(m.getTitle() + ": " + m.describe());
}A query for Media returns objects of the right subclasses:
Hibernate: create table Media (height integer, seconds integer, width integer, id bigint not null, DTYPE varchar(31) not null check ((DTYPE in ('Image','Video'))), title varchar(255), primary key (id), ...)
Hibernate: insert into Media (title,height,width,DTYPE,id) values (?,?,?,'Image',?)
Hibernate: insert into Media (title,seconds,DTYPE,id) values (?,?,'Video',?)
Hibernate: select m1_0.id,m1_0.DTYPE,m1_0.title,m1_0.height,m1_0.width,m1_0.seconds from Media m1_0 order by m1_0.id
Cover: image 1200x630
Demo: video, 95 sWith SINGLE_TABLE the whole hierarchy lives in one table. The DTYPE column (discriminator) stores the class name, and columns of other subclasses stay empty. This is the default strategy and the fastest one: no joins.
JOINED
Replace the strategy with InheritanceType.JOINED, and each class gets its own table linked by the id:
Hibernate: create table Image (height integer not null, width integer not null, id bigint not null, primary key (id))
Hibernate: create table Media (id bigint not null, title varchar(255), primary key (id))
Hibernate: create table Video (seconds integer not null, id bigint not null, primary key (id))
Hibernate: insert into Media (title,id) values (?,?)
Hibernate: insert into Image (height,width,id) values (?,?,?)
Hibernate: select ... from Media m1_0 left join Image m1_1 on m1_0.id=m1_1.id left join Video m1_2 on m1_0.id=m1_2.id order by m1_0.id| Strategy | Tables | Pros and cons |
|---|---|---|
SINGLE_TABLE | One | Fast; subclass columns must allow null |
JOINED | One per class | Clean structure; every query joins tables |
TABLE_PER_CLASS | One per concrete class | Polymorphic queries use union; rarely used |
Common fields without a hierarchy
Often you just want every entity to have the same id and creation date. That is what @MappedSuperclass is for:
// src/main/java/com/example/blog/BaseEntity.java
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue
private Long id;
private LocalDateTime createdAt = LocalDateTime.now();
public Long getId() {
return id;
}
}A class Tag extends BaseEntity gets the table Tag (createdAt timestamp(6), id bigint not null, name varchar(255), ...). The superclass has no table of its own.
Common mistake
A @MappedSuperclass is not an entity, so it cannot be queried:
java.lang.IllegalArgumentException: org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'BaseEntity'If you need queries across all subclasses, make the base class an @Entity with an inheritance strategy.