我们今天聊一下Spring Data JPA
里的三个方法,分别是getOne
,findOne
以及findById
。
咋一看三个方法都能返回一个结果集,用哪个好像都没问题。我当初也是这么想的,后来在写作业的过程中出错了,真相只有一个。
我的例子是查询一个一对一映射关系的实体,极为简单,我就不上代码了;用findById
则可以实现我们的需求,而使用getOne
查询后对结果集进行打印,出现下面的异常。
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
这个异常好像跟使用哪个方法没太大的关系,因为他是在得到查询的结果集后,打印这个结果集的时候出现的,且映射关系默认使用FetchType.EAGER
,实体的toString
方法仅对实体自己的属性做打印,不处理映射关系,莫非是因为得到的一个代理对象,不能映射成实体?还希望路过的高人指点一二。
最后使用findOne
,也能准确的查到结果,有趣的是打印了三条查询语句。
翻开官方的API,找找这几个磨人的方法都在哪:
-
getOne
来自JpaReposiroty
接口,对于传入的标识则返回一个实体的引用;且取决于该方法的实现,可能会出现EntityNotFoundException
,并会拒绝一些无效的标识;
-
findById
来自CrudRepository
接口,通过它的id
返回一个实体;
-
findOne
来自QueryByExampleExecutor
接口,返回一个通过Example
匹配的实体或者null
;
那他们的区别也就是:
-
getOne
返回一个实体的引用,无结果会抛出异常; -
findById
返回一个Optional
对象; -
findOne
返回一个Optional
对象,可以实现动态查询;
而Optional
代表一个可能存在也可能不存在的值。
注:文中使用的版本为Spring Data JPA 2.1.8.RELEASE
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。