JPA和Hibernate的關系


JPA Java Persistence API,是Java EE 5的標准ORM接口,也是ejb3規范的一部分。

Hibernate,當今很流行的ORM框架,是JPA的一個實現,但是其功能是JPA的超集。

JPA和Hibernate之間的關系,可以簡單的理解為JPA是標准接口,Hibernate是實現。那么Hibernate是如何實現與JPA的這種關系的呢。

Hibernate主要是通過三個組件來實現的,及hibernate-annotation、hibernate-entitymanager和hibernate-core。

hibernate-annotation是Hibernate支持annotation方式配置的基礎,它包括了標准的JPA annotation以及Hibernate自身特殊功能的annotation。

hibernate-core是Hibernate的核心實現,提供了Hibernate所有的核心功能。

hibernate-entitymanager實現了標准的JPA,可以把它看成hibernate-core和JPA之間的適配器,它並不直接提供ORM的功能,而是對hibernate-core進行封裝,使得Hibernate符合JPA的規范。

 

Maven依賴:

<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.2.4.Final</version>
</dependency>
<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.2.Final</version>
</dependency>
<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-annotations</artifactId>
            <version>3.5.6-Final</version>
</dependency>

 

下面重點介紹一下hibernate-entitymanager包的主要類及實現。

HibernatePersistence.java,實現了JPA的PersistenceProvider接口,它提供createEntityManagerFactory和createContainerEntityManagerFactory兩個方法來創建EntityManagerFactory對象,這兩個方法底層都是調用的EJB3Configuration對象的buildEntityManagerFactory方法,來解析JPA配置文件persistence.xml,,並創建EntityManagerFactory對象。

EntityManagerFactory對象的實現是EntityManagerFactoryImpl類,這個類有一個最重要的private屬性就是Hibernate的核心對象之一SessionFactory。這個類最重要的方法是createEntityManager,來返回EntityMnagaer對象,而sessionFactory屬性也傳入了該方法。

EntityManager對象的實現是EntityManagerImpl類,這個類繼承自AbstractEntityManagerImpl類,在AbstractEntityManager類中有一個抽象方法getSession來獲得Hibernate的Session對象,正是在這個Session對象的實際支持下,EntityManagerImpl類實現了JPA的EntityManager接口的所有方法,並完成實際的ORM操作。

此外,hibernate-entitymanager包中還有QueryImpl類利用EntityManagerImpl的支持實現了JPA的Query接口;TransactionImpl利用EntityManagerImpl的支持實現了JPA的EntityTransaction接口。

至此,Hibernate通過hibernate-entitymanager包完成了對於JPA的全部支持工作。

最后,補充一個讓我感到意外的問題:

JPA中的Query對象的getSingleResult()方法,當查詢不到結果時,拋出NoResultException、當查詢到多個結果時,拋出NonUniqueResultException;並且NoResultException和NonUniqueResultException都是RuntimeException。

這樣有兩個問題:

1、我認為getSingleResult方法應該允許查詢不到結果的情況存在的,此時它返回null即可,沒有必要拋出異常;

2、即使需要在查詢不到結果或者查詢到多個結果時拋出異常,也不應該拋出RuntimeException,因為這樣表示不需要代碼顯示的用try-catch塊來捕獲這些異常,也就不會引起用戶對這兩個異常的重視。

目前解決這個問題我使用的方法是

try{ 
    Object o = query.getSingleResult(); } catch (NoResultException ex){ return null; }catch(NonUniqueResultException ex) { o = queryObject.getResultList(); return ((List)o).get(0); }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM