JPA和Hibernate的关系
2015-06-15 00:28
489 查看
原文网址:http://hi.baidu.com/tianpaomian/blog/item/fd618bdeed8ef55394ee375d.html
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的规范。
下面重点介绍一下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);}
1. 喜欢
+
2. 我想在此补充一点,你还可以得到Hibernate的session通过调用
例如:
+
3. 使用像@PrePersist,PostPersist@@预更新注解,没有额外的配置EntityManagerFactory的方法。
使用类似的回调SessionFactory将需要额外的努力
参考:http://stackoverflow.com/questions/5640778/hibernate-sessionfactory-vs-entitymanagerfactory
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的规范。
下面重点介绍一下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);}
1. 喜欢
EntityManagerFactory和
EntityManager。它们是由JPA标准定义的。
SessionFactory和
Session平静休眠特定的。该
EntityManager调用引擎盖下的Hibernate会话。如果你需要特定的函数不可用的
EntityManager,你可以通过调用获取会话:
Session session = entityManager.unwrap(Session.class);
+
2. 我想在此补充一点,你还可以得到Hibernate的session通过调用
getDelegate()从法
EntityManager。
例如:
Session session = (Session) entityManager.getDelegate();
+
3. 使用像@PrePersist,PostPersist@@预更新注解,没有额外的配置EntityManagerFactory的方法。
使用类似的回调SessionFactory将需要额外的努力
参考:http://stackoverflow.com/questions/5640778/hibernate-sessionfactory-vs-entitymanagerfactory
相关文章推荐
- 用hibernate分页查询的底层方法
- CentOS网络问题汇总
- iOS项目立项
- xml解析
- jpa date 多表查询
- HDU 2923 Einbahnstrasse(最短路 Floyd)
- hibernate 实现多表连接查询 查询结果映射到自定义类中
- Hibernate中关于多表连接查询hql 和 sql 返回值集合中对象问题
- 黑马程序员--Java基础Day09
- Linux系统编程——线程同步与互斥:POSIX无名信号量
- C++ 64位自定义随机数生成器的使用 <random> 参照C++11
- 常用linux服务主配置文件
- unity开发关于IOS平台接入之自动化构建管线
- 2.7 带多条趋势线的散点图
- node.js 初体验
- 记录谁向您的网站添加了新的链接?
- 视频:如何制作.9图片
- 经典C语言程序编码-利润计算
- 你所不了解的javascript操作DOM的细节知识点(一)
- netlink socket编程之why & how