Pro dan Kontra Menggunakan ORM (Object Relational Mapping)
4 min read

Pro dan Kontra Menggunakan ORM (Object Relational Mapping)

ORM (Object Relational Mapping) adalah salah satu pendekatan yang sangat populer dalam pengembangan aplikasi modern. Hampir semua framework besar—baik di Java, Ruby, Python, PHP, maupun Go—menyediakan ORM sebagai default choice untuk berinteraksi dengan database.

Namun, di balik kemudahan dan produktivitas yang ditawarkan, ORM juga membawa sejumlah konsekuensi, terutama dalam hal optimasi query. Banyak engineer (termasuk saya) memiliki concern serius: query menjadi sulit dilacak, sulit dioptimasi, dan kadang tidak disadari performanya sudah bermasalah hingga masuk ke production.

Artikel ini ditulis dengan latar belakang tersebut: bukan untuk menolak ORM, tetapi untuk memahami secara jujur kapan ORM membantu dan kapan ORM justru menjadi beban.


Apa Itu ORM?

ORM adalah teknik untuk memetakan tabel database relasional ke dalam bentuk objek di bahasa pemrograman. Dengan ORM:

  • Tabel → Class
  • Row → Object
  • Column → Attribute
  • Relasi (FK) → Object reference / collection

Contoh sederhana:

  • Tanpa ORM → menulis SQL manual
  • Dengan ORM → memanggil User.find(id) atau user.posts

Tujuan utamanya adalah:

  • Mengurangi boilerplate SQL
  • Menyatukan logika data dengan domain object
  • Meningkatkan produktivitas developer

Kelebihan Menggunakan ORM

Produktivitas Developer Tinggi

ORM menghilangkan kebutuhan menulis SQL untuk operasi umum:

  • CRUD
  • Pagination
  • Relasi antar tabel

Ini sangat terasa pada:

  • Proyek baru
  • Tim kecil
  • MVP atau prototyping

Engineer bisa fokus ke business logic, bukan ke query detail.

Abstraksi Database

ORM membuat aplikasi:

  • Lebih independen dari vendor database
  • Relatif mudah migrasi dari MySQL → PostgreSQL (dalam batas tertentu)

Selama tidak menggunakan fitur SQL yang terlalu spesifik, ORM membantu menjaga portability.

Keamanan (Default Safer)

Sebagian besar ORM:

  • Otomatis melakukan parameter binding
  • Mengurangi risiko SQL Injection

Untuk engineer junior, ini adalah guardrail yang sangat membantu.

Konsistensi Struktur Data

Dengan ORM:

  • Struktur data terdefinisi dalam satu tempat (model/entity)
  • Relasi antar tabel lebih eksplisit

Ini mempermudah:

  • Code review
  • Onboarding engineer baru

Kekurangan Menggunakan ORM (Bagian yang Sering Diremehkan)

Query Sulit Dilacak (Hidden SQL)

Concern terbesar.

Dengan ORM:

  • SQL tidak terlihat secara eksplisit di kode
  • Query tersebar di berbagai method, relation, hook, atau lazy loading

Contoh masalah:

  • user.orders.items.product terlihat sederhana
  • Tapi bisa menghasilkan puluhan query tanpa disadari (N+1 problem)

Saat performa bermasalah:

  • Engineer harus menyalakan query logger
  • Membaca SQL hasil generate ORM
  • Mencocokkan kembali ke kode tingkat tinggi

Ini tidak trivial, bahkan untuk engineer senior.

Optimasi Query Menjadi Sulit

Optimasi database membutuhkan:

  • Kontrol penuh terhadap SQL
  • Pemahaman index
  • Pemahaman execution plan (EXPLAIN)

Dengan ORM:

  • Query kompleks sulit diekspresikan secara natural
  • Optimasi sering berbenturan dengan abstraksi ORM

Akibatnya:

  • Engineer “menyerah” dan menerima query tidak optimal
  • Atau memaksakan ORM hingga kodenya menjadi tidak readable

Over-fetching dan Under-fetching Data

ORM cenderung:

  • Mengambil kolom lebih banyak dari yang dibutuhkan
  • Mengambil relasi yang tidak selalu diperlukan

Contoh:

  • Hanya butuh id dan name
  • Tapi ORM melakukan SELECT *

Pada skala kecil ini tidak terasa. Pada skala besar, ini berdampak pada:

  • Memory
  • Network I/O
  • Latency

N+1 Query Problem

Masalah klasik ORM.

Contoh pola:

  • Ambil 100 user
  • Untuk setiap user, ORM ambil orders

Tanpa disadari:

  • 1 query ambil user
  • 100 query ambil orders

Total: 101 query

Ini sering:

  • Tidak terlihat di code review
  • Baru ketahuan saat load meningkat

Debugging dan Performance Tuning Lebih Mahal

Tanpa ORM:

  • SQL terlihat jelas
  • Bottleneck cepat ditemukan

Dengan ORM:

  • Perlu tracing
  • Perlu mapping dari SQL → kode
  • Perlu memahami internal ORM

Waktu debugging meningkat signifikan.

False Sense of Simplicity

ORM sering memberi ilusi:

“Database itu cuma object storage”

Padahal:

  • Database punya cost model
  • Index, join, aggregation, dan locking sangat berpengaruh

Engineer yang terlalu lama hidup di ORM berisiko:

  • Lemah di SQL
  • Lemah di database design

Dampak ORM terhadap Optimasi Query (Fokus Utama)

Saat Aplikasi Masih Kecil

  • ORM sangat membantu
  • Masalah performa jarang muncul

Saat Data dan Traffic Membesar

  • Query mulai lambat
  • Analisa semakin sulit
  • Perubahan kecil di kode bisa menghasilkan SQL berbeda

Saat Incident Terjadi

  • Sulit menjawab: query ini berasal dari mana?
  • Sulit melakukan hotfix cepat

Di fase ini, ORM sering berubah dari helper menjadi liability.


Kapan ORM Cocok Digunakan?

ORM cocok jika:

  • CRUD-heavy application
  • Kompleksitas query rendah
  • Tim banyak engineer junior
  • Fokus ke speed of delivery
  • Performa bukan bottleneck utama

Kapan ORM Sebaiknya Dibatasi atau Dihindari?

Pertimbangkan tidak full ORM jika:

  • Query kompleks dan heavily optimized
  • Banyak reporting / aggregation
  • Traffic tinggi dan latency-sensitive
  • Perlu kontrol penuh terhadap SQL

Pendekatan Hybrid (Yang Paling Realistis)

Banyak tim matang memilih pendekatan ini:

  • ORM untuk:

    • Simple CRUD
    • Write operations
  • Raw SQL / Query Builder untuk:

    • Read-heavy query
    • Reporting
    • Query kritikal performa

Keuntungan:

  • Tetap produktif
  • Tetap punya kontrol optimasi

Best Practice Jika Tetap Menggunakan ORM

  1. Aktifkan query logging di environment non-prod
  2. Wajib paham SQL dan EXPLAIN meskipun pakai ORM
  3. Review query, bukan hanya kode
  4. Hindari lazy loading default
  5. Gunakan explicit select field
  6. Pisahkan read model dan write model jika perlu

Penutup

ORM bukan musuh. Tapi ORM juga bukan solusi universal.

Masalah muncul bukan karena ORM itu buruk, tetapi karena:

  • Terlalu percaya abstraksi
  • Kurang visibilitas ke SQL
  • Optimasi dianggap belakangan

Dengan memahami pro dan kontra secara seimbang, kita bisa:

  • Menggunakan ORM secara sadar
  • Menghindari jebakan performa
  • Menjaga aplikasi tetap scalable

Pada akhirnya, database tetaplah database, bukan sekadar object store.