Operasi basis data biasa mengenal akronim CRUD yang berarti Create (Buat), Read (Baca), Update (Modifikasi), dan Delete (Hapus). Operasi-operasi ini lazim diterapkan pada bisnis sehari-hari. Namun, pada beberapa data kritikal, operasi hapus tidak boleh benar-benar dilakukan. Yang dilakukan hanya mengubah agar data tersebut tidak terlihat/aktif di aplikasi, namun secara fisik masih ada di basisdata.

JPA Pada Umumnya

Sebagai contoh, misalkan ada kelas entitas akun yang biasa dibuat oleh orang.

// ... import omitted
@Entity
public class Account{
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ACCOUNT_ID")
    long id;

    String name;

    // JPA needs default constructor
    public Account() {}

    public Account(String name) {
        this.name = name;
    }

    // ... Setter and getter omitted
}

Pada kelas Account.java seperti biasa kita membuat kolom-kolom biasa. Lalu, misalkan dengan Spring Boot JPA, dibuatkan sebuah kelas Repository yang akan digunakan untuk melakukan operasi-operasi CRUD:

public interface AccountRepository extends CrudRepository <Account, Long>{

}

Saya akan menunjukkan selanjutnya bagaimana mengubah pola CRUD menjadi CRUH (Hide). Operasi CRUH hanya istilah saya saja yang artinya hanya menyembunyikan, bukan menghapus data (hapus-sembunyi).

CRUH dengan JPA

Salah satu solusi untuk operasi hapus-sembunyi adalah dengan menggunakan penanda. Kolom penanda ini digunakan untuk menyatakan data tersebut sudah terhapus. Sehingga, klien/aplikasi hanya akan mendapatkan data yang tidak ditandai. Solusi ini dapat dicapai dengan minimal melalui Spring JPA.

Pada JPA, yang diubah cukup hanya kelas entitas saja. Hal-hal yang diperlu dilakukan:

  • Ubah operasi hapus dengan menandai kolum penanda. Misalnya pada baris 4 operasi SQL hapus dimodifikasi dengan mengubah nilai deleted menjadi ‘1’.
  • Ubah operasi baca dengan mengambil data yang kolom penandanya belum diset. Misalnya pada baris 5, dicari deleted tidak sama dengan ‘1’.
  • Buat sebuah kolom penanda. Misalnya pada baris 13, ditambahkan kolom deleted. 
  • Pada baris 12 dibuatkan sebuah anotasi @JsonIgnore agar kolom ini tidak muncul pada akses data melalui Repository. Jadi, kolom ini benar-benar transparan.
  • Jangan lupa diinisialisasi data deleted pada konstruktor.
// ... import omitted
@Entity
@SQLDelete(sql="UPDATE item SET deleted = '1' WHERE item_id = ?")
@Where(clause="deleted <> '1'")
public class Account{
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ACCOUNT_ID")
    long id;

    String name;

    @JsonIgnore
    String deleted;

    // JPA needs default constructor
    public Account() {}

    public Account(String name) {
        this.name = name;
        this.deleted = '0';
    }

    // ... Setter and getter omitted
}

Semoga bermanfaat.