Intellij 调试器越过休眠对象值是空的

Posted

技术标签:

【中文标题】Intellij 调试器越过休眠对象值是空的【英文标题】:Intellij debugger step over hibernate objects values are empty 【发布时间】:2019-05-10 03:49:02 【问题描述】:

当我使用 Intellij 跨过休眠对象时,调试窗口中的对象似乎为空。标记为$$_hibernate_interceptor

假设我有一些简单的代码,如下所示

Subscription subscription  = subscriptionRepository.getOne(1l);
log.info("add breakpoint debug code stopped here")

我想查看在Debug: 窗口中从subscriptionRepository 返回并分配给订阅对象的值。

查看屏幕截图,显示这在我的计算机上的样子。

如您所见,大多数变量值似乎是空的,但是如果我对订阅对象执行 toString(),它将输出在 inteceptor 窗口中标记为 null 的值。所以它们并不是真正的空。

这里有几个问题

什么是$$_hibernate_interceptor

进一步的发现

只有在我使用默认的repository.getOne 时才会返回拦截器。如果我使用 findBy 或我自己的 findByField,它不会调用拦截器并在调试窗口中显示值。

这里发生了什么,为什么 getOne 显示拦截器而其他不显示?

【问题讨论】:

getOne() 返回一个未初始化的代理。这就是该方法的全部意义所在。调用该代理的方法(如 toString())将初始化代理,即告诉 Hibernate 执行查询并从数据库加载数据。所以你看到的是完全正常和预期的。这是通过字节码生成发生的,而 bytebuddy 拦截器是(AFAIK)将拦截方法调用并初始化代理的对象。 Thabks 的反馈是有道理的。那么在调试面板中查看对象的选项是什么? 我猜你可以使用“评估表达式”工具来调用toString()? jetbrains.com/help/idea/evaluating-expressions.html 【参考方案1】:

如您所见,您的订阅类型是Subscription$HibernateProxy$...。这是因为 Hibernate 会在您使用它们时从数据库中延迟加载属性。

直到它们第一次被访问,比如在toString() 中,它们都是空的。 您可以通过在“subscription.toString()”上添加一个变量监视(小 + 图标)轻松地避开这一点。

findByIdgetOne 的区别在于前者返回的是惰性代理,而后者使用的是热切加载的对象。关于为什么can be found here的一些信息。

【讨论】:

以上是关于Intellij 调试器越过休眠对象值是空的的主要内容,如果未能解决你的问题,请参考以下文章

PHP 打印布尔值是空的,为啥?

在IntelliJ调试中保存对象的状态?

在按钮单击文本框值是空的使用 asp.net mvc 显示警报?

微信支付成功后,微信回调值是空的,怎么解决

打开会话的休眠异常。我该如何调试呢?

易语言 取telnet返回值问题