[問題] Spring Data JPA no Session問題

作者: jtorngl (Pedrosa go!)   2022-05-06 12:54:33
※問題類別: Spring Data JPA
※系統環境: bellsoft-jdk-11.0.14.1
很久沒有使用 JPA,最近可能會用到
又回頭看了 Spring Data JPA
一開始使用 Spring Boot 練習
第一問題通常會遇到 infinite recursion 的 JsonMappingException
所以使用 Jackson 的各種 annotation 或是轉 DTO 來解
因為覺得 Spring Boot 背後做太多事,可能會錯過什麼
所以改用 Spring 來練習一下
果不其然就發生了 LazyInitializationException - no Session
查了一下,Spring Boot 的 spring.jpa.open-in-view 預設為 true
讓 entity 在脫離 transaction scope 時
還能使用 oiv 的 connection 去查 lazy entity 的資料
不過查資料時,是建議關閉這個功能,畢竟拉長佔用 connection 的時間
而查到的幾種解法
1. 把 @Transactional 設定在操作 lazy entity 的 method
因為 Spring Data JPA 執行流程,會導到 SimpleJpaRepository 來處理
而 SimpleJpaRepository 在 class 上宣告了 @Transactional(readOnly = true)
因為練習的 service 內的 method,可能會查詢多次
不希望每個查詢都使用一個 read only transaction
所以在 XxxService 的 class 也使用 @Transactional(readOnly = true)
希望多個查詢使用同一個 read only transaction
所以我在 XxxService 的 class 上也使用 @Transactional(readOnly = true)
然後在執行 insert, update, delete 的 method 使用 @Transactional
https://imgur.com/2nVTBXH
但如果要使用 @Transactional 來解 no Session 的錯誤
那就變成要把 @Transactional 設定在 controller 的 method 了
這和 open-in-view 的做法似乎差別不大,只是用同一個 connection 而已?
2. 把 entity 關聯設為 FetchType.EAGER
即使沒用到,也強制查詢關聯的 table,應該也不會這樣使用
3. Spring Boot 設定 hibernate.enable_lazy_load_no_trans=true
(Spring 的話,在設定 EntityManagerFactory 時,設定 jpa properties)
似乎也是 Hibernate 實做,另開個 Session 查詢 lazy entity
作者: ssccg (23)   2022-05-06 14:30:00
transaction又不是spring data jpa才有的東西,lazy關聯不過就是個抽象化的query,不管是用jpa還是從底層driver自己寫,都一樣要自己決定這個query要在哪個transaction執行啊要像看起來一樣方便就open-in-view,從上到下都用entity不然總是要自己決定transaction要包到哪,在這之上就不去亂用entity關聯,而是明確重下一次query。而且包到哪應該是從資料是否需要transaction決定,不是api操作方不方便決定至於DTO,主要還是因為要用DTO才用,標誌transaction分界只是順便而已
作者: ntpuisbest (阿龍)   2022-05-06 18:45:00
關聯很多實務上很多都是用jdbc template吧
作者: ssccg (23)   2022-05-06 19:03:00
我個人DTO用mapstruct,transaction通常只開到我自己的Repository層(在這裡面才再看情用jpa/jdbc),出了這層就是DTO,會分有載入關聯和沒有的API不過基本上這問題還是看你做的系統需求,就像你說的本來就是個很淺的data service就沒差
作者: Jichang (C.C.Lemon)   2022-05-15 02:47:00
不用open session 可以用Hibernate.initialize也可以batch query 出來塞進去

Links booklink

Contact Us: admin [ a t ] ucptt.com