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()”上添加一个变量监视(小 + 图标)轻松地避开这一点。
findById
和getOne
的区别在于前者返回的是惰性代理,而后者使用的是热切加载的对象。关于为什么can be found here的一些信息。
【讨论】:
以上是关于Intellij 调试器越过休眠对象值是空的的主要内容,如果未能解决你的问题,请参考以下文章