MyEclipse 內建 Hibernate 反向工程工具,可從資料庫表自動生成 Entity、DAO、Hibernate 配置檔與 SessionFactory 工具類。本文記錄關鍵步驟與「必須手動添加事務才能持久化」的核心坑點。
Entity (POJO)、DAO、SessionFactory、hbm.xml、hibernate.cfg.xml。src/
├── com.pyf.test/ # Entity (User.java)
├── com.pyf.test.dao/ # UserDAO.java
├── com.pyf.test.util/ # HibernateSessionFactory.java
└── hibernate.cfg.xml # 核心配置
package com.pyf.test2;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.pyf.test.*;
import com.pyf.test.dao.UserDAO;
public class Test1 {
public static void main(String[] args) {
User user = new User(5, "aa", 5);
UserDAO userdao = new UserDAO();
// ❌ 錯誤示範:僅調用 save(),無事務 → 數據不會真正寫入資料庫
// userdao.save(user);
// ✅ 正確做法:手動開啟事務、提交、關閉 Session
Transaction tx = userdao.getSession().beginTransaction();
try {
userdao.save(user);
tx.commit(); // 提交事務,SQL 才真正生效
} catch (Exception e) {
tx.rollback(); // 異常回滾
e.printStackTrace();
} finally {
userdao.getSession().close(); // 釋放資源
}
/* 等價於底層原始 API:
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();
*/
}
}
| 場景 | 行為 | 原因 |
|---|---|---|
無事務調用 save() | 內存中生成 INSERT 語句,但未發送至 DB | Hibernate 預設需事務邊界觸發 flush/commit |
有事務 beginTransaction() → commit() | 數據成功持久化 | 事務提交觸發 session.flush() 並提交 DB 事務 |
最佳實踐:實際專案請使用 Spring 宣告式事務(@Transactional) 或 OpenSessionInViewFilter 統一管理 Session 與事務邊界,避免在業務代碼中手動控制導致資源洩漏或事務不一致。
public class HibernateSessionFactory {
private static final SessionFactory sessionFactory;
static {
try {
Configuration cfg = new Configuration().configure(); // 讀取 hibernate.cfg.xml
sessionFactory = cfg.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
return sessionFactory.openSession(); // 每次調用開新 Session
}
}
參考教程:MyEclipse Hibernate 反向工程圖文教程