java 板


LINE

※問題類別: 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 ------------------------------------------------------------------- 查到以上的做法都是不建議的 4. 避免使用雙向關聯 但是單向關聯就會發生了 總不會 entity 都不要關聯,每個 entity 自行操作? 5. 使用 JOIN FETCH 使用 @Query 自己下 JPQL 6. 使用 DTO Spring Data JPA 的 projection 功能 雖然 interface based projection 有支援 nested projection 但是使用 @Query 時,JPQL 卻不知怎麼下 例如有一個 Employee 的 entity,和關聯的 Department https://imgur.com/rebQiC7 projection 的 interface 這樣宣告 https://imgur.com/pcB86Q6 JPQL 或 native SQL 都無法設值到 department 的 deptName https://imgur.com/XRhI92i 除非把關聯的 entity 內的 field 全部移到 Employee 內,只有一層的結構 而 class based projection 是另外定義 DTO class 但是不支援 nested projection 也就是如果我希望 DTO 能長這樣,似乎是不可行的 https://imgur.com/EzAIeV6 而且 DTO 的 constructor 似乎要符合查詢的 field 數目 我使用 overload 的 constructor 想用在多種查詢 也遇過 no suitable constructor 之類的錯誤 以及 ConverterNotFoundException: No converter found ... 的錯誤 難不成不同的查詢,就需要一個對應的 DTO 嗎?! 6.1. 使用 library 把 entity 轉成 DTO 也有看到使用 modelmapper 做 converter 的範例 不過這個範例我不知道為什麼可以成功 https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application 因為他的 service 和 controller 都沒看到使用 @Transactional 也就是使用 SimpleJpaRepository 的 read only transaction 那在 controller 使用 ModelMapper 時,就會炸 no Session 了 我是把 ModelMapper 移到 service 內執行 因為 @Transactional 也都是掛在 service layer 6.2. 是否直接把 entity 做 deep copy 到結構完全一樣的 DTO 就好了 還沒測試,只是突然想到 以前在用 JPA 時,只是使用而沒深入了解 沒有發生 no Session 的錯誤 同樣雙向關聯的 entity,同樣是把 transaction 掛在 service layer 現在回想,當時在 render JSP 時,為什麼沒問題呢? 後面還有 N + 1 的問題 目前查到是使用 FETCH JOIN,或是 JPA 2.1 的 @EntityGraph Spring JDBC 用久了,現在覺得 Data JPA 用起來還挺不順手 如果要直接操作 entity,就要處理 no Session 的問題 很多教學的範例,其 entity 都只是簡單的 field,甚至沒有關聯的 entity 但實務上應該不會這樣吧? 如果要操作 DTO,表示要大量使用 JPQL 或 Data JPA 的 query methods? 題外話 不知道 JOOQ 好不好用,Spring Boot 有看到 但似乎都是 Data JPA 和 MyBatis 較多 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.249.65.177 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/java/M.1651812876.A.961.html
1F:→ ssccg: transaction又不是spring data jpa才有的東西,lazy關聯不 05/06 14:30
2F:→ ssccg: 過就是個抽象化的query,不管是用jpa還是從底層driver自己 05/06 14:31
3F:→ ssccg: 寫,都一樣要自己決定這個query要在哪個transaction執行啊 05/06 14:32
4F:→ ssccg: 要像看起來一樣方便就open-in-view,從上到下都用entity 05/06 14:35
5F:→ ssccg: 不然總是要自己決定transaction要包到哪,在這之上就不去亂 05/06 14:36
6F:→ ssccg: 用entity關聯,而是明確重下一次query。而且包到哪應該是從 05/06 14:38
7F:→ ssccg: 資料是否需要transaction決定,不是api操作方不方便決定 05/06 14:40
8F:→ ssccg: 至於DTO,主要還是因為要用DTO才用,標誌transaction分界只 05/06 14:48
感謝 s大說明 其實是自己在練習,把查到的方式都試一遍 然後想問實務上,使用哪種方式居多而已 當然實務也還是得看情況選擇使用,沒有標準答案 只是以前都只是 MVC + JSP 在使用 加上短暫使用 JPA,後來就長期使用 JDBC template 使用 JDBC template 其實就是一次查詢 把 view 要用到的資料一次查回到 VO 重點在 SQL 的調教而已 現在會需要使用 Data JPA,使用 RESTful 回傳 JSON 但是 JSON 的內容依 API 需要有各種內容 例如可能只有 Employee,也可能會需要有 Department 流量不大的情況,的確可以使用 open-in-view 直接把 entity output JSON 就好 然後去處理 N + 1 的 SQL 問題 只是想問看看,哪個方式處理會比較好 例如流量若較大,能盡早結束 transaction 關閉 connection 是否就是使用 Data JPA 的 projection 直接轉 DTO 那就是要去解決,怎麼樣能像 entity 那樣結構的 DTO 而已 若要符合自己提問的情況,依照過去使用 JDBC template 的情況 會使用 DTO 來處理,只是 兩種 projection 我都試不出符合 DTO 的結構
9F:→ ssccg: 是順便而已 05/06 15:09
※ 編輯: jtorngl (111.249.65.177 臺灣), 05/06/2022 15:31:03
10F:推 ntpuisbest: 關聯很多實務上很多都是用jdbc template吧 05/06 18:45
11F:→ ssccg: 我個人DTO用mapstruct,transaction通常只開到我自己的 05/06 19:03
12F:→ ssccg: Repository層(在這裡面才再看情用jpa/jdbc),出了這層就是 05/06 19:05
13F:→ ssccg: DTO,會分有載入關聯和沒有的API 05/06 19:07
14F:→ ssccg: 不過基本上這問題還是看你做的系統需求,就像你說的本來就 05/06 19:08
15F:→ ssccg: 是個很淺的data service就沒差 05/06 19:10
16F:推 Jichang: 不用open session 可以用Hibernate.initialize 05/15 02:47
17F:→ Jichang: 也可以batch query 出來塞進去 05/15 02:48







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP