Hibernate 4+ 所帶來的改變

jopen 11年前發布 | 89K 次閱讀 Hibernate 持久層框架

近期為了仔細的學習了一下Hibernate,就在官網上下了最新的hibernate-release-4.1.9.Final 版本,筆者最開始接觸Hibernate時是3+版本,雖然4+版本帶來了一下改變不是很大,但是搭建一個新的Hibernate框架對于一個不能夠真正理解Hibernate的心的人來說也不是一件信手拈來的事,我在搭建的時候遇到了很多疑惑,最讓我不解的是最新版本的英文版手冊貌似跟3+版本相差不大。目前遇到的問題在官網、手冊、源碼和各大高手的博客上都得到了解決,此篇就是整理于各位大拿的的博客以及自己的見解,如涉有錯誤歡迎指出。

  • 創建SessionFactory時buildSessionFactory()方法過期
    A 在3.6.8版本中,可以直接用
SessionFactory sf = new Configuration()
    .configure()    //    直接用hibernate.cfg.xml來進行配置和創建
    .buildSessionFactory();
B 在4.0.0版本中,因Configuration().configure()方法被廢除了,故用以下方式來創建
Configuration config = new Configuration()
            .addResource("org/monday/domain/Customer.hbm.xml");
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
            .buildServiceRegistry();
SessionFactory sf = config.buildSessionFactory(serviceRegistry);
在此方法中默認使用hibernate.properties文件來進行配置,而hibernate.properties文件中不能添加映射文件(.hbm.xml),所以只能用.addResource("org/monday/domain/Customer.hbm.xml")來添加映射文件,這里必須是全路徑

使用如下方法時,讀取hibernate.cfg.xml時會出錯(找不到元素 'hibernate-configuration' 的聲明)
Unable to perform unmarshalling at line number 4 and column 26 in RESOURCE hibernate.cfg.xml
可能是這個版本對DTD不識別,或者是方法運用錯誤

ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                .configure()    //想通過這個來讀取hibernate.cfg.xml來進行配置
                .buildServiceRegistry();
SessionFactory sf = new MetadataSources( serviceRegistry )            
            .buildMetadata()
            .buildSessionFactory();
C 在4.0及以上版本中,用hibernate.cfg.xml來創建sessionFactory的方法

從Hibernate 4之后,Configuration類中,原先常用的,獲取SessionFactory的方法buildSessionFactory()被標記為過時,官方建議使用buildSessionFactory(ServiceRegistry sr)這個方法來獲取SessionFactory。新的方法,我理解,是因為用戶有可能(雖然很罕見)根據不同的cfg.xml文件來創建出不同的Configuration對象實例,新的方法可以根據不同的實例來構建出不同的ServiceRegistry,進而得到不同需求的sessionFactory.

這樣做的具體用例我雖然還沒有遇到,但是可以想象,新的方法對分布式數據庫將有良好的支持。

比如,一個分布式數據庫系統中包含了分布在多個不同主機,不同類型的數據庫,我們開發一個WEB應用,要求對這些數據庫都要進行操作,假如這些數據庫的信息分別寫在了多個cfg.xml中,那么,我們就可以根據這些不同的配置文件,生成針對不同數據庫SessionFactory,并將其保存在一個Map中,數據庫名作為鍵值,這樣我們就可以在實現DAO層的時候,根據訪問不同數據庫的需要而獲取到不用的Session.


      private static final SessionFactory sessionFactory = buildSessionFactory();
                private static ServiceRegistry serviceRegistry;    
                Configuration configuration = new Configuration();
                configuration.configure();
                serviceRegistry = new ServiceRegistryBuilder().applySettings(
                                configuration.getProperties()).buildServiceRegistry();
                return configuration.buildSessionFactory(serviceRegistry);
本人測試代碼:
package cn.com.zyx.model;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class StudentTest {
public static void main(String[] args) {
    Student s = new Student();
    s.setName("111");
    s.setSex("男");

    Configuration cfg = new Configuration();
    cfg.configure();
    //SessionFactory sf=cfg.configure().buildSessionFactory();//*過期方法*解析Hibernate.cfg.xml 然后返回一個已經擁有配置選項的Configuration
    ServiceRegistry sr=new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
    //SessionFactory類似數據庫庫的一個Connection
    SessionFactory sf =cfg.buildSessionFactory(sr);
    //打開一個連接
    Session session =sf.openSession();
    //開始一個事務
    session.beginTransaction();
    session.save(s);
    //獲得一個事務,并提交
    session.getTransaction().commit();
    //關閉連接
    session.close();
    //關閉工廠
    sf.close();

}
}


  • Error applying BeanValidation relational constraints錯誤的解決
錯誤示例:
Exception in thread "main" org.hibernate.HibernateException: Error applying BeanValidation relational constraints
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.applyRelationalConstraints(BeanValidationIntegrator.java:219)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:126)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:303)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1750)
at cn.com.zyx.model.StudentTest.main(StudentTest.java:20)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.applyRelationalConstraints(BeanValidationIntegrator.java:208)
... 4 more
Caused by: org.hibernate.HibernateException: Unable to build the default ValidatorFactory
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:524)
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.applyDDL(TypeSafeActivator.java:119)
... 9 more
Caused by: javax.validation.ValidationException: Unable to instantiate Configuration.
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:272)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:111)
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:521)
... 10 more

在hibernate.hbm.xml中加上
<property name="javax.persistence.validation.mode">none</property>


javax.persistence.validation.mode默認情況下是auto的,就是說如果不設置的話它是會自動去你的classpath下面找一個bean-validation**包,但是找不到,所以beanvalitionFactory錯誤。

來自:http://blog.csdn.net/zyxesc/article/details/8591999

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!