SpringDataJpa : How to handle inheritance with Entities
Points to Remember
- Mark your Base Entity class with annotation
@MappedSuperclass
. - Define all common fields and their getter setters in this class.
- Make the base class abstract.
- Make all fields as protected so that they can be accessed in inheriting class without getters and setter.
- You can also define
@PrePersist
and@PreUpdate
in this class.
Fields that should be in the Base Entity
Your Base Entity class should have only those field that need to be common for all your entities that will inherit this class.
Sample Base Entity that you should use might look as follows
package com.ekiras.domain.base;
import javax.persistence.*;
import java.util.Date;
/**
* @author ekiras
*/
@MappedSuperclass
public class BaseDomain {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
@Temporal(TemporalType.TIMESTAMP)
protected Date dateCreated;
@Temporal(TemporalType.TIMESTAMP)
protected Date lastUpdated;
@Override
public String toString() {
return "BaseDomain{" +
"id=" + id +
", dateCreated=" + dateCreated +
", lastUpdated=" + lastUpdated +
'}';
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
}
In the above BaseDomain
class we have marked it with annotation @MappedSuperclass
. This will enforce that no table is created for this class in the database.
@MappedSuperclass
A class designated with the
MappedSuperclass
annotation can be mapped in the same way as an entity except that the mappings will apply only to its subclasses since no table exists for the mapped superclass itself. When applied to the subclasses the inherited mappings will apply in the context of the subclass tables.
Now, let us inherit this base class in the User
Entity class. So the User.java class may be as follows
package com.ekiras.domain;
import com.ekiras.domain.base.BaseDomain;
import javax.persistence.Entity;
/**
* @author ekiras
*/
@Entity
public class User extends BaseDomain{
private String email;
private String name;
private String password;
@Override
public String toString() {
return super.toString()+" :: User{" +
"email='" + email + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
When we will run the project it will create the following table in the database.
mysql> show tables;
+-----------------------+
| Tables_in_jpa_mapping |
+-----------------------+
| user |
+-----------------------+
1 row in set (0.00 sec)
mysql> desc user;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| date_created | datetime | YES | | NULL | |
| last_updated | datetime | YES | | NULL | |
| email | varchar(255) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| password | varchar(255) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
This shows that,
- No table is created for the
BaseDomain
class. - All the field od the
BaseDmain
class are included in the inherting class User.
No comments: