الفصل 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 يدير تلقائيًا:
-
التعيين الكائني-العلاقاتي (ORM)
- فئة Java ↔ جدول SQL
- سمة Java ↔ عمود SQL
-
توليد SQL
findAll()→SELECT * FROM productssave()→INSERT INTO products ...
-
إدارة المخطط
- إنشاء/تعديل الجداول (استراتيجيات 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 |
|---|---|
| PostgreSQL | org.hibernate.dialect.PostgreSQLDialect |
| MySQL 8+ | org.hibernate.dialect.MySQL8Dialect |
| SQL Server | org.hibernate.dialect.SQLServerDialect |
| Oracle 12c+ | org.hibernate.dialect.Oracle12cDialect |
| H2 | org.hibernate.dialect.H2Dialect |
| MariaDB | org.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 |
|---|---|---|
| التطوير | update | true |
| الاختبارات | create-drop | true |
| الإنتاج | validate أو none | false |
الخطوة التالية
الآن بعد أن أتقنت Hibernate، دعنا ننتقل إلى الفصل 4 لاكتشاف Lombok وتقليل الكود المتكرر!