咱們今天聊一下Spring Data JPA
裏的三個方法,分別是getOne
,findOne
以及findById
。
咋一看三個方法都能返回一個結果集,用哪一個好像都沒問題。我當初也是這麼想的,後來在寫做業的過程當中出錯了,真相只有一個。
個人例子是查詢一個一對一映射關係的實體,極爲簡單,我就不上代碼了;用findById
則能夠實現咱們的需求,而使用getOne
查詢後對結果集進行打印,出現下面的異常。spring
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
這個異常好像跟使用哪一個方法沒太大的關係,由於他是在獲得查詢的結果集後,打印這個結果集的時候出現的,且映射關係默認使用FetchType.EAGER
,實體的toString
方法僅對實體本身的屬性作打印,不處理映射關係,莫非是由於獲得的一個代理對象,不能映射成實體?還但願路過的高人指點一二。api
最後使用findOne
,也能準確的查到結果,有趣的是打印了三條查詢語句。spa
翻開官方的API,找找這幾個磨人的方法都在哪:hibernate
getOne
來自JpaReposiroty
接口,對於傳入的標識則返回一個實體的引用;且取決於該方法的實現,可能會出現EntityNotFoundException
,並會拒絕一些無效的標識;
findById
來自CrudRepository
接口,經過它的id
返回一個實體;
findOne
來自QueryByExampleExecutor
接口,返回一個經過Example
匹配的實體或者null
;
那他們的區別也就是:代理
getOne
返回一個實體的引用,無結果會拋出異常;findById
返回一個Optional
對象;findOne
返回一個Optional
對象,能夠實現動態查詢;而Optional
表明一個可能存在也可能不存在的值。code
注:文中使用的版本爲Spring Data JPA 2.1.8.RELEASE
。對象