Hai, di materi kali ini saya mau ngebahas tentang Inherintance Mapping dengan Metode MappedSuperclass. Untuk mencoba mapping ini, kita membutuhkan 2 tabel yang memiliki column yang hampir sama contohnya mobil sama motor berikut adalah perancangan databasenya:

erd

Implementasi Entity superclass:

package com.maryanto.dimas.bootcamp.example.mapping.inherintance.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
@MappedSuperclass
public class KendaraanMappedSuperclass {
@Column(name = "nama", length = 50)
private String nama;
@Column(name = "jumlah_roda", length = 2)
private Integer jumlahRoda;
@Column(name = "jumlah_cylinder", length = 3)
private Integer jumlahCylinder;
@Column(name = "cc", length = 4)
private Integer cc;
@Column(name = "nama_pabrikan", nullable = false, length = 50)
private String namaPabrikan;
}

Implementasi Entity child mobil:

package com.maryanto.dimas.bootcamp.example.mapping.inherintance.entity;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Data
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
@Entity
@Table(name = "mobil_mappedsuperclass", schema = "inherintance")
@GenericGenerator(name = "uuid_gen", strategy = "uuid2")
public class MobilMappedSuperclass extends KendaraanMappedSuperclass {
@Id
@GeneratedValue(generator = "uuid_gen")
@Column(name = "id", length = 64)
private String id;
@Column(name = "jumlah_kursi", length = 1)
private Integer jumlahKursi;
@Column(name = "is_all_wheel_drive", nullable = false)
private boolean allWheelDrive;
}

Implementasi Entity child motor:

package com.maryanto.dimas.bootcamp.example.mapping.inherintance.entity;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Data
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
@Entity
@Table(name = "motor_mappedsuperclass", schema = "inherintance")
@GenericGenerator(name = "uuid_gen", strategy = "uuid2")
public class MotorMappedSuperClass extends KendaraanMappedSuperclass {
@Id
@GeneratedValue(generator = "uuid_gen")
@Column(name = "id", length = 64)
private String id;
@Column(name = "jenis_rantai")
private String jenisRantai;
}

Implementasi DAO untuk mobil:

package com.maryanto.dimas.bootcamp.example.mapping.inherintance.dao;
import com.maryanto.dimas.bootcamp.example.mapping.inherintance.entity.MobilMappedSuperclass;
import com.maryanto.dimas.bootcamp.example.repository.CrudRepository;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import java.util.List;
import java.util.Optional;
public class MobilMappedSuperClassDao implements CrudRepository<MobilMappedSuperclass, String> {
private Session session;
public MobilMappedSuperClassDao(Session session) {
this.session = session;
}
@Override
public MobilMappedSuperclass save(MobilMappedSuperclass value) throws HibernateException {
String returnKey = (String) this.session.save(value);
value.setId(returnKey);
return value;
}
@Override
public MobilMappedSuperclass update(MobilMappedSuperclass value) throws HibernateException {
this.session.update(value);
return value;
}
@Override
public boolean removeById(String value) throws HibernateException {
throw new UnsupportedOperationException();
}
@Override
public Optional<MobilMappedSuperclass> findById(String value) throws HibernateException {
MobilMappedSuperclass mobil = this.session.find(MobilMappedSuperclass.class, value);
return mobil != null ? Optional.of(mobil) : Optional.empty();
}
@Override
public List<MobilMappedSuperclass> findAll() throws HibernateException {
throw new UnsupportedOperationException();
}
}

Implementasi DAO untuk motor:

package com.maryanto.dimas.bootcamp.example.mapping.inherintance.dao;
import com.maryanto.dimas.bootcamp.example.mapping.inherintance.entity.MotorMappedSuperClass;
import com.maryanto.dimas.bootcamp.example.repository.CrudRepository;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import java.util.List;
import java.util.Optional;
public class MotorMappedSuperClassDao implements CrudRepository<MotorMappedSuperClass, String> {
private Session session;
public MotorMappedSuperClassDao(Session session) {
this.session = session;
}
@Override
public MotorMappedSuperClass save(MotorMappedSuperClass value) throws HibernateException {
String returnKey = (String) this.session.save(value);
value.setId(returnKey);
return value;
}
@Override
public MotorMappedSuperClass update(MotorMappedSuperClass value) throws HibernateException {
this.session.update(value);
return value;
}
@Override
public boolean removeById(String value) throws HibernateException {
throw new UnsupportedOperationException();
}
@Override
public Optional<MotorMappedSuperClass> findById(String value) throws HibernateException {
MotorMappedSuperClass motor = this.session.find(MotorMappedSuperClass.class, value);
return motor != null ? Optional.of(motor) : Optional.empty();
}
@Override
public List<MotorMappedSuperClass> findAll() throws HibernateException {
throw new UnsupportedOperationException();
}
}

Kemudian kita buat unit testingnya seperti berikut:

package com.maryanto.dimas.bootcamp.test.mapping.inherintance;
import com.maryanto.dimas.bootcamp.example.config.HibernateConfiguration;
import com.maryanto.dimas.bootcamp.example.mapping.inherintance.dao.MobilMappedSuperClassDao;
import com.maryanto.dimas.bootcamp.example.mapping.inherintance.dao.MotorMappedSuperClassDao;
import com.maryanto.dimas.bootcamp.example.mapping.inherintance.entity.MobilMappedSuperclass;
import junit.framework.TestCase;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Ignore;
import org.junit.Test;
import java.util.Optional;
@Ignore
@Slf4j
public class TestMappedSuperClass extends TestCase {
private Session session;
private MobilMappedSuperClassDao mobilDao;
private MotorMappedSuperClassDao motorDao;
@Override
protected void setUp() throws Exception {
log.info("init hibernate session");
this.session = HibernateConfiguration.getSession();
this.mobilDao = new MobilMappedSuperClassDao(session);
this.motorDao = new MotorMappedSuperClassDao(session);
}
@Test
public void testSaveMobil() {
MobilMappedSuperclass hondaBrio = MobilMappedSuperclass.builder()
.nama("Honda BRIO")
.allWheelDrive(false)
.cc(1000)
.jumlahCylinder(4)
.jumlahKursi(4)
.jumlahRoda(4)
.namaPabrikan("PT. Honda Motor Company")
.build();
Transaction trx = this.session.beginTransaction();
hondaBrio = this.mobilDao.save(hondaBrio);
trx.commit();
Optional<MobilMappedSuperclass> optional = this.mobilDao.findById(hondaBrio.getId());
assertTrue("mobil is present", optional.isPresent());
hondaBrio = optional.get();
log.info("mobil: {}", hondaBrio);
}
@Override
protected void tearDown() throws Exception {
log.info("destroy hibernate session!");
this.session.close();
}
}

Jika di running maka hasilnya seperti berikut:

INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@1e1e837d] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: 
    
    create table inherintance.mobil_mappedsuperclass (
       id varchar(64) not null,
        cc int4,
        jumlah_cylinder int4,
        jumlah_roda int4,
        nama varchar(50),
        nama_pabrikan varchar(50) not null,
        is_all_wheel_drive boolean not null,
        jumlah_kursi int4,
        primary key (id)
    )
Hibernate: 
    
    create table inherintance.motor_mappedsuperclass (
       id varchar(64) not null,
        cc int4,
        jumlah_cylinder int4,
        jumlah_roda int4,
        nama varchar(50),
        nama_pabrikan varchar(50) not null,
        jenis_rantai varchar(255),
        primary key (id)
    )
Jan 16, 2021 12:00:08 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: 
    insert 
    into
        inherintance.mobil_mappedsuperclass
        (cc, jumlah_cylinder, jumlah_roda, nama, nama_pabrikan, is_all_wheel_drive, jumlah_kursi, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?)
[main] INFO com.maryanto.dimas.bootcamp.test.mapping.inherintance.TestMappedSuperClass - mobil: MobilMappedSuperclass(super=KendaraanMappedSuperclass(nama=Honda BRIO, jumlahRoda=4, jumlahCylinder=4, cc=1000, namaPabrikan=PT. Honda Motor Company), id=c5a7398c-a79c-4abd-9c55-deb3ec1e2bad, jumlahKursi=4, allWheelDrive=false)
[main] INFO com.maryanto.dimas.bootcamp.test.mapping.inherintance.TestMappedSuperClass - destroy hibernate session!