java.lang.NullPointerException
at com.reitgn.dao.impl.AdvancedRegistrationDaoImpl.addAdvancedRegistration(AdvancedRegistrationDaoImpl.java:34)
at com.reitgn.service.impl.AdvanceRegistrationServiceImpl.addAdvancedRegistration(AdvanceRegistrationServiceImpl.java:34)
at com.reitgn.servlet.RegisterServlet.doPost(RegisterServlet.java:71)
...
錯誤日誌中關鍵資訊:
java.lang.NoSuchMethodError: org.hibernate.SessionFactory.openSession()Lorg/hibernate/classic/Session
根本原因: Hibernate 4 起已棄用並移除 HibernateDaoSupport 與 HibernateTemplate。原專案碼繼承 HibernateDaoSupport 並呼叫 getHibernateTemplate().save(),導致執行期找不到對應方法。
提供的 applicationContext.xml 使用 LocalSessionFactoryBean 整合 Hibernate 4,事務管理配置正確,但 DAO 層寫法不相容。
public class AdvancedRegistrationDaoImpl extends HibernateDaoSupport {
public void addAdvancedRegistration(AdvancedRegistration ar) {
getHibernateTemplate().save(ar); // Hibernate 4 無此方法
}
}
@Repository
public class AdvancedRegistrationDaoImpl {
@Autowired
private SessionFactory sessionFactory;
public void addAdvancedRegistration(AdvancedRegistration ar) {
Session session = sessionFactory.getCurrentSession(); // 獲取當前事務性 Session
session.save(ar); // 直接使用原生 API
}
}
| 特性 | Hibernate 3 (舊) | Hibernate 4+ (新) |
|---|---|---|
| DAO 基類 | HibernateDaoSupport | 無需繼承,注入 SessionFactory |
| 操作介面 | HibernateTemplate | Session / Query / Criteria |
| Session 獲取 | getSession() / openSession() | getCurrentSession() (推薦) |
| 事務綁定 | Template 自動管理 | Spring @Transactional 管理 |
extends HibernateDaoSupportSessionFactory 替代 setSessionFactory()getHibernateTemplate().save() 改為 sessionFactory.getCurrentSession().save()session.createQuery() 或 session.createCriteria()<tx:annotation-driven/> 已啟用完成上述修改後,NullPointerException 將消失,且程式碼更符合現代 Hibernate 最佳實踐。