JPA + Hibernate Inheritance - @MappedSuperclass Example
February 20, 2023
On this page, we will lean using JPA @MappedSuperclass
annotation in Hibernate inheritance application.
1. The
@MappedSuperclass
annotation is annotated at a class level in which we configure mappings of columns that may be common for some database tables.
2. When
@MappedSuperclass
class is inherited by a class, all mapping information of this class, are applied to its subclass.
3. The
@MappedSuperclass
class does not represent a separate table. It only designates a class whose mapping information is applied to the entities that inherit from it.
4. The mappings of
@MappedSuperclass
class are configured in the same way as the mappings of @Entity
class. The difference is that @Entity
represents a table but @MappedSuperclass
represents no table.
5. The mapping information of
@MappedSuperclass
class can be overridden by @Entity
class using @AssociationOverride
and @AttributeOverride
annotations or corresponding XML elements.
Using @MappedSuperclass Annotation
Create a class with some common fields of some database tables and annotate that class with@MappedSuperclass
annotation.
@MappedSuperclass public class Person { @Id @Column(name = "id") private Integer id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; @Column(name = "gender") private String gender; @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "coll_id") private College college; ------- }
Person
class can be common fields of classes like Student
and Teacher
. We can notice that Person
class is not representing any table.
Now create
Student
class extending Person
class. All the mappings of Person
class will be available in Student
.
@Entity @Table(name = "student") public class Student extends Person { @Column(name = "course") private String course; ------ }
Using @AssociationOverride Annotation
The@AssociationOverride
annotation is used to override a mapping for an entity relationship.
In the
Person
class, @JoinColumn
is joining using coll_id column.
@ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "coll_id") private College college;
@AssociationOverride
annotation as following.
@Entity @AssociationOverride( name="college", joinColumns=@JoinColumn(name="college_id") ) @Table(name = "teacher") public class Teacher extends Person { ------ }
Using @AttributeOverride Annotation
The@AttributeOverride
annotation is used to override the mapping of a basic property or field, or Id property or field.
In the
Person
class, name property is mapped with name column. In Teacher
entity, the table teacher has different name column i.e. teacher_name. We can override name
attribute from Person
class to map with teacher_name using @AttributeOverride
annotation as following.
@Entity @AttributeOverride( name = "name", column = @Column(name = "teacher_name") ) @Table(name = "teacher") public class Teacher extends Person { ------ }
Complete Example
1. Technologies Used1. Java 19
2. Hibernate 6
3. Jakarta Persistence API 3
4. MySQL 5.5
2. MySQL Database
CREATE TABLE `college` ( `coll_id` INT(5) NOT NULL, `name` VARCHAR(100) NULL DEFAULT NULL, `location` VARCHAR(50) NULL DEFAULT NULL, PRIMARY KEY (`coll_id`) ) CREATE TABLE `student` ( `id` INT(5) NOT NULL, `name` VARCHAR(50) NOT NULL, `age` INT(3) NOT NULL, `gender` VARCHAR(10) NOT NULL, `course` VARCHAR(20) NOT NULL, `coll_id` INT(5) NOT NULL, PRIMARY KEY (`id`) ) CREATE TABLE `teacher` ( `id` INT(5) NOT NULL, `teacher_name` VARCHAR(50) NOT NULL, `age` INT(3) NOT NULL, `gender` VARCHAR(10) NOT NULL, `subject` VARCHAR(50) NOT NULL, `college_id` INT(5) NOT NULL, PRIMARY KEY (`id`) )
<dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.1.6.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>6.0.0.Alpha7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.32</version> </dependency> </dependencies>
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="com.concretepage"> <description>Procedure Demo</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" /> <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost/concretepage" /> <property name="jakarta.persistence.jdbc.user" value="root" /> <property name="jakarta.persistence.jdbc.password" value="cp" /> </properties> </persistence-unit> </persistence>
HibernateUtil.java
package com.concretepage.util; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; public class HibernateUtil { private static final EntityManagerFactory emFactory; static { emFactory = Persistence.createEntityManagerFactory("com.concretepage"); } public static EntityManager getEntityManager(){ return emFactory.createEntityManager(); } }
package com.concretepage.entity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; @Entity @Table(name = "college") public class College { @Id @Column(name = "coll_id") private Integer collId; @Column(name = "name") private String name; @Column(name = "location") private String location; public College(Integer collId, String name, String location) { this.collId = collId; this.name = name; this.location = location; } // Setters and Getters }
package com.concretepage.entity; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.MappedSuperclass; @MappedSuperclass public class Person { @Id @Column(name = "id") private Integer id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; @Column(name = "gender") private String gender; @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "coll_id") private College college; public Person(Integer id, String name, Integer age, String gender, College college) { this.id = id; this.name = name; this.age = age; this.gender = gender; this.college = college; } // Setters and Getters }
package com.concretepage.entity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Table; @Entity @Table(name = "student") public class Student extends Person { @Column(name = "course") private String course; public Student(Integer id, String name, Integer age, String gender, College college, String course) { super(id, name, age, gender, college); this.course = course; } // Setters and Getters }
package com.concretepage.entity; import jakarta.persistence.AssociationOverride; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.JoinColumn; import jakarta.persistence.Table; @Entity @AssociationOverride(name="college", joinColumns=@JoinColumn(name="college_id")) @AttributeOverride(name = "name", column = @Column(name = "teacher_name")) @Table(name = "teacher") public class Teacher extends Person { @Column(name = "subject") private String subject; public Teacher(Integer id, String name, Integer age, String gender, College college, String subject) { super(id, name, age, gender, college); this.subject = subject; } // Setters and Getters }
package com.concretepage; import com.concretepage.entity.College; import com.concretepage.entity.Student; import com.concretepage.entity.Teacher; import com.concretepage.util.HibernateUtil; import jakarta.persistence.EntityManager; public class Main { public static void main(String[] args) { EntityManager entityManager = HibernateUtil.getEntityManager(); entityManager.getTransaction().begin(); College college = new College(11, "ABC College", "Port Blair"); Student student = new Student(101, "Mohan", 25, "Male", college, "B.Tech"); Teacher teacher = new Teacher(301, "Sohan", 25, "Male", college, "Match"); entityManager.persist(student); entityManager.persist(teacher); entityManager.getTransaction().commit(); entityManager.close(); } }
