انتقل إلى المحتوى الرئيسي

الفصل 3: Hibernate واستراتيجيات DDL

مقدمة​

سؤال: كيف يقوم Hibernate بإنشاء الجداول في قاعدة البيانات الخاصة بك؟

إجابة: بفضل استراتيجيات DDL (لغة تعريف البيانات).

في هذا الفصل، ستفهم:

  • ما هو Hibernate
  • استراتيجيات DDL الخمسة (none, validate, update, create, create-drop)
  • متى تستخدم كل استراتيجية
  • كيفية تكوين Hibernate لـ PostgreSQL

ما هو Hibernate؟​

تعريف​

Hibernate هو التنفيذ لـ JPA (Java Persistence API) الذي يستخدمه Spring Boot.

تشبيه:

  • JPA = الواجهة (الـ "ماذا") 📄
  • Hibernate = التنفيذ (الـ "كيف") ⚙️

مثال:

// JPA يحدد الواجهة
@Entity
public class Product { ... }

// Hibernate ينفذ التعيين
// يولد SQL تلقائيًا

دور Hibernate​

Hibernate يدير تلقائيًا:

  1. التعيين الكائني-العلاقاتي (ORM)

    • فئة Java ↔ جدول SQL
    • سمة Java ↔ عمود SQL
  2. توليد SQL

    • findAll() → SELECT * FROM products
    • save() → INSERT INTO products ...
  3. إدارة المخطط

    • إنشاء/تعديل الجداول (استراتيجيات DDL)

استراتيجيات DDL الخمسة​

نظرة عامة​

الاستراتيجيةالسلوكالاستخدام الموصى به
noneلا يوجد إجراءالإنتاج (مع Flyway/Liquibase)
validateيتحقق من صحة المخطط، لا يعدل شيئًاالإنتاج
updateيحدث المخطط (يضيف فقط)التطوير
createيعيد إنشاء المخطط عند كل بدء تشغيلالاختبارات
create-dropينشئ عند البدء، يحذف عند الإيقافالاختبارات

1. ddl-auto: none​

السلوك: Hibernate لا يلمس قاعدة البيانات.

متى تستخدمه: في الإنتاج مع أدوات الترحيل (Flyway, Liquibase).

التكوين:

spring:
jpa:
hibernate:
ddl-auto: none

مثال:

بدء تشغيل التطبيق...
→ Hibernate لا ينشئ/يعدل أي جدول
→ يجب أن تكون الجداول موجودة بالفعل

المزايا:

  • ✅ تحكم كامل في المخطط
  • ✅ لا مفاجآت في الإنتاج

العيوب:

  • ❌ يجب عليك إدارة الترحيلات يدويًا

2. ddl-auto: validate​

السلوك: Hibernate يتحقق من أن المخطط يتوافق مع الكيانات، لكنه لا يعدله.

متى تستخدمه: في الإنتاج للتحقق من التناسق.

التكوين:

spring:
jpa:
hibernate:
ddl-auto: validate

مثال:

بدء تشغيل التطبيق...
→ Hibernate يقارن الكيانات مع الجداول
→ إذا كان هناك اختلاف → خطأ وتوقف

خطأ نموذجي:

Schema-validation: missing column [price] in table [products]

المزايا:

  • ✅ يكتشف التناقضات
  • ✅ يؤمن بدء التشغيل

العيوب:

  • ❌ لا يصحح تلقائيًا

3. ddl-auto: update​

السلوك: Hibernate يحدث المخطط (يضيف أعمدة/جداول، لكنه لا يحذف أبدًا).

متى تستخدمه: في التطوير.

التكوين:

spring:
jpa:
hibernate:
ddl-auto: update

مثال:

الكيان الأولي:

@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
}

قاعدة البيانات:

CREATE TABLE products (
id BIGINT PRIMARY KEY,
name VARCHAR(255)
);

تعديل الكيان:

@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
private Double price; // جديد
}

بدء تشغيل التطبيق:

ALTER TABLE products ADD COLUMN price DOUBLE PRECISION;

✅ تم إضافة العمود تلقائيًا!


المزايا:

  • ✅ مريح في التطوير
  • ✅ لا حاجة لإدارة المخطط يدويًا

العيوب:

  • ❌ لا يحذف الأعمدة القديمة
  • ❌ قد يسبب تناقضات على المدى الطويل
  • ❌ خطر في الإنتاج

4. ddl-auto: create​

السلوك: Hibernate يعيد إنشاء جميع الجداول عند كل بدء تشغيل (يحذف ويعيد الإنشاء).

متى تستخدمه: للاختبارات الآلية.

التكوين:

spring:
jpa:
hibernate:
ddl-auto: create

مثال:

بدء تشغيل التطبيق...
→ DROP TABLE products;
→ CREATE TABLE products (...);
→ جميع البيانات مفقودة

المزايا:

  • ✅ مخطط دائمًا نظيف
  • ✅ مثالي للاختبارات

العيوب:

  • ❌ فقدان كامل للبيانات عند كل بدء تشغيل
  • ❌ لا تستخدم أبدًا في الإنتاج

5. ddl-auto: create-drop​

السلوك: مثل create, لكن يحذف أيضًا الجداول عند إيقاف التطبيق.

متى تستخدمه: للاختبارات الوحدوية/التكاملية.

التكوين:

spring:
jpa:
hibernate:
ddl-auto: create-drop

مثال:

بدء تشغيل التطبيق...
→ DROP TABLE products;
→ CREATE TABLE products (...);

... اختبارات ...

إيقاف التطبيق...
→ DROP TABLE products;

المزايا:

  • ✅ بيئة اختبار نظيفة
  • ✅ لا توجد بيانات متبقية

العيوب:

  • ❌ فقدان كامل للبيانات
  • ❌ لا تستخدم أبدًا في الإنتاج

التكوين الكامل لـ PostgreSQL​

تكوين التطوير​

الملف: application-dev.yml

spring:
datasource:
url: jdbc:postgresql://localhost:5432/dev_db
username: postgres
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver

jpa:
hibernate:
ddl-auto: update # مريح في التطوير
show-sql: true # عرض الاستعلامات
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: true # تنسيق SQL

تكوين الإنتاج​

الملف: application-prod.yml

spring:
datasource:
url: jdbc:postgresql://prod-server:5432/prod_db
username: prod_user
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver

jpa:
hibernate:
ddl-auto: validate # تحقق فقط
show-sql: false # لا توجد سجلات SQL في الإنتاج
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect

تكوين الاختبارات​

الملف: application-test.yml

spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:

jpa:
hibernate:
ddl-auto: create-drop # ينظف بعد كل اختبار
show-sql: true

لهجات Hibernate​

ما هي اللهجة؟​

اللهجة هي تكييف Hibernate لقاعدة بيانات معينة.

تشبيه: مثل اللهجات الإقليمية للغة (الفرنسية في فرنسا مقابل الفرنسية في كيبيك).


اللهجات الشائعة​

قاعدة البياناتلهجة Hibernate
PostgreSQLorg.hibernate.dialect.PostgreSQLDialect
MySQL 8+org.hibernate.dialect.MySQL8Dialect
SQL Serverorg.hibernate.dialect.SQLServerDialect
Oracle 12c+org.hibernate.dialect.Oracle12cDialect
H2org.hibernate.dialect.H2Dialect
MariaDBorg.hibernate.dialect.MariaDBDialect

لماذا تحديد لهجة؟​

مثال: توليد معرف تلقائي الزيادة

PostgreSQL:

CREATE TABLE products (
id BIGSERIAL PRIMARY KEY, -- PostgreSQL
name VARCHAR(255)
);

MySQL:

CREATE TABLE products (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- MySQL
name VARCHAR(255)
);

بدون لهجة: Hibernate لا يعرف أي صيغة يستخدم.

مع لهجة: Hibernate يولد SQL الصحيح لقاعدة البيانات الخاصة بك.


سجلات SQL وتصحيح الأخطاء​

عرض استعلامات SQL​

التكوين:

spring:
jpa:
show-sql: true # تفعيل سجلات SQL
properties:
hibernate:
format_sql: true # تنسيق SQL للقراءة

وحدة التحكم:

Hibernate: 
insert
into
products
(name, price, id)
values
(?, ?, ?)

عرض قيم المعلمات​

التكوين:

logging:
level:
org.hibernate.SQL: DEBUG # سجلات SQL
org.hibernate.type.descriptor.sql.BasicBinder: TRACE # قيم المعلمات

وحدة التحكم:

Hibernate: 
insert
into
products
(name, price, id)
values
(?, ?, ?)

binding parameter [1] as [VARCHAR] - [Laptop]
binding parameter [2] as [DOUBLE] - [999.99]
binding parameter [3] as [BIGINT] - [1]

استراتيجيات موصى بها​

ملخص بصري​

التطوير
↓
ddl-auto: update
show-sql: true
↓
تغييرات سريعة
الجداول تُنشأ تلقائيًا

---

الاختبارات
↓
ddl-auto: create-drop
show-sql: true
↓
بيئة نظيفة
البيانات تُحذف بعد الاختبارات

---

الإنتاج
↓
ddl-auto: validate (أو none)
show-sql: false
↓
لا تعديلات تلقائية
الترحيلات تُدار بواسطة Flyway/Liquibase

أخطاء شائعة​

الخطأ 1: الجدول غير موجود​

الخطأ:

Table "products" doesn't exist

السبب: ddl-auto: none أو validate, لكن الجداول غير موجودة.

الحل: استخدم ddl-auto: update أو أنشئ الجداول يدويًا.


الخطأ 2: عدم تطابق المخطط​

الخطأ:

Schema-validation: missing column [price] in table [products]

السبب: ddl-auto: validate, لكن الكيان والجدول يختلفان.

الحل:

  • قم بتغيير إلى update مؤقتًا
  • أو عدل الجدول يدويًا

الخطأ 3: فقدان البيانات بعد إعادة التشغيل​

الخطأ: جميع بياناتي تختفي عند إعادة التشغيل!

السبب: ddl-auto: create أو create-drop.

الحل: قم بتغيير إلى update أو validate.


ملخص​

النقاط الرئيسية​

✅ Hibernate = تنفيذ JPA
✅ 5 استراتيجيات DDL: none, validate, update, create, create-drop
✅ التطوير: update
✅ الإنتاج: validate أو none + Flyway
✅ الاختبارات: create-drop
✅ اللهجة: تكييف Hibernate لقاعدة البيانات الخاصة بك


قائمة التحقق لاستراتيجيات DDL​

البيئةالاستراتيجيةshow-sql
التطويرupdatetrue
الاختباراتcreate-droptrue
الإنتاجvalidate أو nonefalse

الخطوة التالية​

الآن بعد أن أتقنت Hibernate، دعنا ننتقل إلى الفصل 4 لاكتشاف Lombok وتقليل الكود المتكرر!

➡️ الفصل 4: Lombok

⬅️ الفصل السابق: Jakarta vs Javax

⬅️ العودة إلى الوحدة 4