Hibernate 5.0以后的懒加载实现及懒加载失效问题解决

背景

 目前工作中有个需求,需要对单张表的某个字段使用大字段(长字符串)来存储数据。使用oracle存储,即该字段会使用CLOB来存储长字符内容。那么该字段通过jpa进行实体设计如图所示:
在这里插入图片描述
 其中@Basic指定为懒加载模式,这里对大字段使用懒加载模式是比较合适的,例如在列表查询时往往是不用直接展示该字段内容的,一般只有在修改或查看详情时才会进行该字段的展示,我本次的工作需求即是如此,故采用懒加载。

问题

 问题也伴随着@Basic注解的使用而来了,开始我单纯的以为简单地使用@Basic(fetch = FetchType.LAZY)后便可以实现懒加载了,后面在实际的使用验证后发现这样简单的加注解并没有实现懒加载功能,开启jpa的sql打印后发现,该字段在当前实体查询时也是立即便参与了查询,查询sql如下:
在这里插入图片描述
 由此可见指定懒加载的content字段和其他字段一样都是立即参与了查询。

问题解决

 好了,既然懒加载存在问题那么开始解决呗。打开浏览器打开度娘输入问题“Hibernate @Basic注解懒加载失效”,经过这样的一通对度娘的询问后(这里有点跟不上潮流了chatGPT4都出来了我还在向度娘需求帮助,有时间说啥得搞个账号了),看了各种各样的帖子,其中很多文章都是说利用实体去实现FieldHandled接口,这种方式应该是有用的不过只支持Hibernate5.0及其以下版本的,5.0以后Hibernate有了一些调整,其中FieldHandled接口便不再存在了,那么5.0以后版本的可以利用实现PersistentAttributeInterceptable接口来去手动拦截我们需要实现懒加载的字段。本人工作项目中使用的正是Hibernate5.4版本的,具体代码如下:
在这里插入图片描述
在这里插入图片描述
 测试及执行sql打印效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扩展说明

懒加载的另一种实现方式:

 还有一种可以实现懒加载功能,且不需要在实体中实现PersistentAttributeInterceptable接口。添加Hibernate的字节码增强插件,但该方法存在一个问题:每次都要去重新编译一次代码才能看到懒加载效果,故对实际开发过程中不太友好。所以如果只是长文本内容的懒加载,即和本博客中需求类似,推荐使用上文所说的懒加载实现方式。
 字节码增强插件配置如下(通过maven构建):

<plugin>
                <groupId>org.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>5.4.3.Final</version>
                <executions>
                    <execution>
                        <configuration>
                            <failOnError>true</failOnError>
                            <enableLazyInitialization>true</enableLazyInitialization>
                        </configuration>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

然后在指定字段上加上@Basic(fetch = FetchType.LAZY)即可:
在这里插入图片描述
无需再进行额外代码编写。此处附上Hibernate官方字节码增加部分文档链接:Bytecode Enhancement

懒加载需要注意的问题:

 在存在懒加载字段的调用的方法上应添加上@Transactional注解,保证懒加载字段的首次调用时,session会话不会被关闭。否则会抛出懒加载初始化异常。即如下测试方法便需要添加@Transactional注解:
在这里插入图片描述

idea debug模式下懒加载的验证问题

 由于idea在debug模式下内部会默认调用toString方法,故而如果toString方法包含当前懒加载字段时,则会发现懒加载直接被触发了。所以如果在debug模式下进行懒加载的验证,可以有两种做法:1、手动重写toString方法(排除懒加载字段)2、设置idea debug模式下不去默认调用toString方法。
方法1此处不必细说,方法2设置如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值