Mengenal Identifier Framework Hibernate(Bagian 1)
Bismillah,
Jika pada artikel sebelumnya kita telah berkenalan dengan framework hibernate, pada kesempatan kali ini kita akan belajar lebih dalam lagi yaitu tentang identifier atau jika dianotasikan menggunakan "@Id".
Sebelumnya pernah disinggung sedikit tentang @Id
, yaitu digunakan untuk primary key dalam sebuah entitas atau tabel jika pada database relational. Beberapa sifat dari identifier yaitu
UNIQUE
; nilainya harus berbeda untuk masing-masing rowNOT NULL
; nilainya tidak boleh kosongIMMUTABLE
; ketika diinsert nilainya sudah tidak bisa diubah kembali
Setiap entitas wajib hukumnya mempunyai field/kolom sebagai identifier. Berikut ini adalah model dari identifier pada framework hibernate yang sangat sederhana, kita dapat menggunakan identifier-identifier di bawah ini untuk aplikasi yang akan kita bangun. Beberapa point yang akan dibahas adalah sebagai berikut;
- Assigned identifiers
- Generated identifier
- Generated identifier sequence
- Tabel identifier generator
- UUID identifier generator
- Reference
Assigned identifiers
Untuk memberikan nilai pada identifer jenis ini, aplikasi akan memberikan nilai pada kolom di database ketika menjalankan method save/persist. Sebagai contoh implementasinya adalah di bawah ini
@Entity
@Table
public class Peminjaman implements Serializable {
@Id
private long id;
@Temporal(TemporalType.TIMESTAMP)
private Date tanggal_transaksi;
public Peminjaman() {
}
public Peminjaman(long id, Date tanggal_transaksi) {
this.id = id;
this.tanggal_transaksi = tanggal_transaksi;
}
//Getter setter bisa di-generate menggunakan IDE
Penulisan @Id
pun sangat sederhana, tidak ditambahkan anotasi yang lain setelah @Id
. Kemudian penggunaan tipe data Date, Datetime
, atau Time
jika dimapping ke dalam menggunakan @Temporal
dengan penyesuaian TemporalType
. Selanjutnya untuk unit testnya kurang lebih seperti di bawah ini
@Test
public void testSave() {
Peminjaman p = new Peminjaman();
p.setId(2L);
p.setTanggal_transaksi(new Date());
assertTrue(service.save(p));
}
Jika dilihat potongan unit test di atas, instance dari class Peminjaman
melakukan assign dengan nilai 2. Jika hal tersebut tidak dilakukan tentunya akan terjadi error.
Penggunaan @Id
jenis ini tentunya disesuaikan dengan kebutuhan, biasanya digunakan untuk kolom/field yang dijadikan identifier menggunakan tipe data String
. Contoh penerapannya adalah ketika kita akan membuat sebuah entitas/tabel di database untuk primary key diinput secara manual, sebagai contoh entitas mahasiswa dengan NIM sebagai primary key atau entitas transaksi dengan kode transaksi sebagai primary key.
Generated identifier
Sesuai dengan namanya identifier ini dapat secara automatis memberikan nilai oleh hibernate, gunakan anotasi @GeneratedValue setelah @Id untuk menginformasikan bahwa nilai kolom/field akan dibuatkan secara automatis.
@Entity
@Table
public class Peminjaman implements Serializable {
@Id
@GeneratedValue
private long id;
@Temporal(TemporalType.TIMESTAMP)
private Date tanggal_transaksi;
public Peminjaman() {
}
public Peminjaman(long id, Date tanggal_transaksi) {
this.id = id;
this.tanggal_transaksi = tanggal_transaksi;
}
//getter setter bisa digenerate menggunakan editor
Hanya ditambahkan satu baris perintah anotasi @GeneratedValue
dari class yang sebelumnya, kemudian untuk class unit testnya adalah sebagai berikut
@Test
public void testSave() {
Peminjaman p = new Peminjaman();
p.setTanggal_transaksi(new Date());
assertTrue(service.save(p));
}
Dalam implementasi method pada unit test juga berkurang 1 baris yaitu yang sebelumnya terdapat p.setId(2L)
, ketika menggunakan @GeneratedValue
assign ke kolom/field identifier ditiadakan. Ketika dijalankan coba cek tabel yang terbentuk pada database, hibernate juga akan membuat tabel dengan nama hibernate_sequence
untuk menyimpan nilai selanjutnya dari identifier. Bagaimana jika semua entitas menggunakan identifer menggunakan @GeneratedValue
semua?
Identifier model seperti ini bisa digunakan untuk entitas/tabel yang menyimpan informasi transaksional dan nilainya tidak ditunjukkan kepada seorang pengguna, hanya dikonsumi oleh sistem.
Generated identifier sequence
Sebenarnya model jenis ini adalah perbaikan atau solusi dari anotasi yang hanya @GeneratedValue
, permasalahannya adalah ketika ada banyak entitas yang menggunakan jenis tersebut maka nilai identifiernya akan sama karena mengacu pada tabel hibernate_sequence
. Untuk lebih jelasnya dapat dilhat seperti pada contoh di bawah ini
@Entity
@Table
public class Pengembalian implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "sequence-generator")
@SequenceGenerator(name = "sequence-generator",sequenceName = "sequence_pengembalian",allocationSize = 10)
private long id;
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date tanggalPengembalian;
public Pengembalian() {
}
public Pengembalian(long id, Date tanggalPengembalian) {
this.id = id;
this.tanggalPengembalian = tanggalPengembalian;
}
//getter setter bisa digenerate menggunakan editor
Dalam anotasi @GeneratedValue
terdapat property strategy
dan generator
dan ditambakan anotasi @SequenceGenerator
, sequenceName
digunakan untuk memberikan nama sequence dan allocationSize
ada nilai increment ketika method save/persist dijalankan. Misalkan dibuat nilai 10 berarti setiap data bertambah nilai primary key akan bertambah 10. Untuk unit test masih sama dengan yang sebelumnya, setelah menjalankan unit test coba dicek di database, seharusnya tabel sequence_pengembalian
akan dibuatkan oleh hibernate.
Tabel identifier generator
Generate nilai automatis menggunakan tabel identifer akan membuat sebuah tabel di dalam database oleh hibernate yang berisi informasi nilai identifier dan juga nama tabelnya dari identifier tersebut. Di bawah ini adalah contoh penggunaanya
@Entity
@Table
public class Pengembalian implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,generator = "table-generator")
@TableGenerator(name = "table-generator",table = "table_identifier",pkColumnName = "table_name",valueColumnName = "pengembalian_id",allocationSize = 10)
private long id;
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date tanggalPengembalian;
public Pengembalian() {
}
public Pengembalian(long id, Date tanggalPengembalian) {
this.id = id;
this.tanggalPengembalian = tanggalPengembalian;
}
Pada bagian strategy
diganti menjadi GenerationType.TABLE
dan juga pada generator
menjadi "table-generator"
, kemudian anotasi yang digunakan setelah anotasi @GeneratedValue
adalah @TableGenerator
. Property yang dapat digunakan dalam @TableGenerator
meliputi table
untuk menentukan nama tabelnya, pkColumnName
merupakan primary key dari kolom dari tabel tersebut, dan juga valueColumnName
berfungsi sebagai nama kolom dari sebuah identifier. Kemudian jalankan unit testnya dan cek di database, seharusnya akan ada tabel baru yang terbentuk.
UUID identifier generator
Hibernate juga menyediakan mekanisme pembuatan identifier menggunakan UUID
, UUID
merupakan kepanjangan dari Universallly unique identifier
digunakan untuk mengidentifikasi informasi dalam sistem komputer.
@Entity
@Table
public class Pengembalian implements Serializable {
@Id
@GeneratedValue
private UUID id;
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date tanggalPengembalian;
public Pengembalian() {
}
public Pengembalian(UUID id, Date tanggalPengembalian) {
this.id = id;
this.tanggalPengembalian = tanggalPengembalian;
}
Yang perlu dilakukan adalah hanya menggunakan anotas @GeneratedValue
dan mengubah variabel id menjadi sebuah object dari class UUID
, ketika unit test dijalankan dan dicek di dalam database maka kolom id pada tabel Pengembalian
akan menyimpan data dengan tipe data blob/binary dengan panjang 255. Kemudian kita akan tambahkan property pada anotasi @GeneratedValue
seperti contoh di bawah ini
@Entity
@Table
public class Pengembalian implements Serializable {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(columnDefinition = "VARCHAR(40)")
private String id;
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date tanggalPengembalian;
public Pengembalian() {
}
public Pengembalian(String id, Date tanggalPengembalian) {
this.id = id;
this.tanggalPengembalian = tanggalPengembalian;
}
Pada class Pengembalian
kita tambahkan property generator dengan nama "uuid2"
pada anotasi @GenerateValue
, kemudian ditambahkan @GenericGenerator(name = "uuid2", strategy = "uuid2")
dan @Column(columnDefinition = "VARCHAR(40)")
untuk menentukan definisi kolom pada tabel di database beserta tipe datanya. Silakan dijalankan unit test, selanjutnya cek di tabel Pengembalian
seharusnya nilai id akan diisi oleh UUID dengan standadr IETF RFC 4122. Source code dapat didapatkan di sini.
Demikianlah pembahasan yang masih sederhana mengenai identifier hibernate, pada tulisan yang akan datang mengenai identifier yang multiple value dalam entitas atau sering disebut composite identier. Semoga bermanfaat bagi temen-temen yang baru mulai belajar hibernate, jangan lupa kritik dan saran sangat diharapkan. 🙂