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/cn.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灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP