跳到主要内容

Hibernate 中的常见坑

1. 前言

框架方便了开发者的工作,但是运行速度并没有原生的快。原生开发是直接告诉 JVM 要做什么,框架则是曲线救国,JVM 需要绕些圈子才明白开发者的意图。

显然,框架是要以更多性能消耗、运行速度作为代价的。

本节课,和大家聊一聊使用 Hibernate 中可能遇到的坑。避开这些坑,真正享受 Hibernate 带给开发者的福利。

2. 常见的坑

2.1 延迟加载

延迟加载是 Hibernate 提供的一种性能优化方案,但是,使用时需要注意,必须保持在 Session 生命周期之内。

Hibernate 中的延迟加载有 2 种情形,

  • 如 load()方法。直接调用 load()方法只会产生一个代理对象,只有当访问属性的 get()方法时,才会访问数据。
  • one-to-many、many-to-one、many-to-many 中也可以设置延迟加载,只有访问与当前查询相关联的关系表中的数据时,才会进行数据加载。

因为 Session 生命周期较短,如果要跨组件使用延迟加载功能, 则需保持 Session 生命周期与请求过程相同。WEB 项目开发中,Hibernate 提供有 OpenSessionInViewFilter 过滤器,用来保证请求开始和响应结束的时候,使用同一个 Session。请求开始创建 Session,响应结束关闭 Session。

使用时,这里面会有 1 个坑:不能使用重定向,因为重定向上本质上是两次请求。

2.2 save ()与 merge()

这两个方法都可以接收对象作为参数,但是,save()会把传入的对象转换成持久化状态 ,且返回保存成功后数据的主键。

merge()会返回一个对象,返回的此对象才具有持久化状态。

这里的坑就是千万别误以为传递给 merge()方法的对象具有持久化状态。

2.3 持久化状态

持久化状态的 PO 对象具有同步数据库的能力,但是,请注意,持久化状态只能是在 Session 生命周期之内。现在的项目都是采用的分层体系结构。所以,不要指望业务组件从数据层组件中获取的对象还具有持久化能力,除非你不关闭 Session。

这里的坑就是,持久化状态的对象是有时效性的。

2.4 序列化的

从代码规范上讲,持久化对象是一定要实现序列化接口的,保证能在异构化系统或网络中进行数据传输。

这里有坑就是实现序列化一定要成为持久化对象的标配。

2.5 级联操作

Hibernate 提供的级联操作带来了很多方便。

但是,特别是在双向关联映射的情况下,不要把两边的级联操作全部打开,否则会把不该删除的数据删除掉。

测试数据被级联删除倒无所谓,真实数据被删除了,可能就欲哭无门。

2.6 缓存的使用

Session 级别缓存的应用价值不大,使用 Session 操作完毕后,尽可能进行缓存清理。

SessionFactory 二级缓存需要打开后才能使用,而且一般是依赖第三方插件。缓存可以提高查询数据的速度,但是缓存本身需要消耗资源,所以,缓存的使用需要酌情考虑。

这里有坑就是不要滥用缓存,需要缓存的对象也是需要特别指定的。如此繁琐,相必 HIbernate 也怕你滥用缓存。

2.7 更新和删除

更新和删除之前,一定要先从数据库中查找到对应数据。更新和删除都是针对于数据库中的数据。

这个坑,经常发生在我面授的学生中。

2.8 和其它框架整合

Hibernate 只是解决 JDBC 的问题,在项目中,不可避免的需要和其它框架进行整合。如 Spring 之流,这里面会有一个很大的坑,就是版本兼容问题。

典型的表现就是明明添加了相应的包,但是,出现 class not found。这时就要考虑是否是版本之间的兼容问题。

这个坑有的时候很让人迷惑,明明刚刚添加了相应的包,却告知不存在相应的类。

Spring Boot 提供了 DATA JPA 实现,本质上是使用 Hibernate 的持久化功能。Spring Boot 开箱即用,很好解决了版本的兼容性问题。建议大家使用。

2.9 hbm2ddl 功能

Hibernate 的 hbm2ddl 功能非常强大,使用时一定要注意,什么时候设置为 create,什么时候设置为 update。null

hbm2ddl 功能只用于测试、学习 Hibernate 时,强烈建议不要使用于正式环境,不要指望利用它进行数据库设计。

就怕初学者一看有这么好用的东西,就不管不顾任何时候都使用。

3. 小结

所谓坑,就是你我所走过的路。我遇到的你不一定会遇到,你遇到的我也不一定会碰到。所以,没有任何一个人能告诉你所有。本课程是引路人,走完所有的路程还是要靠自己。

使用 Hibernate 时,总会出现这样或那样的问题,但是,要相信问题肯定能得到解决。本节课通过一些常见问题的解析,让大家少走弯路。

经验还是需要大家自己积累,祝好运。