【问题标题】:What does eclipse do when you inspect variables (while debugging)检查变量时 Eclipse 会做什么(调试时)
【发布时间】:2011-09-21 16:24:07
【问题描述】:

我有一个 org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy 的实例,这引起了一些悲伤:每当我以编程方式尝试访问它时,我都会得到一个空指针异常(即调用 list.size())但是当我第一次使用 Eclipse 的变量检查器检查对象时,我看到Hibernate 生成一条 SQL 语句,列表动态变化。然后一切正常。我怎样才能以编程方式做同样的事情?我试过 list.toString() 但这似乎没有帮助。

更新 1

不知道这是否有帮助,但是当我第一次点击我在显示中看到的列表实例时:

com.sun.jdi.InvocationException occurred invoking method.

然后数据库查询运行,当我再次单击时,我得到正确的.toString() 结果。

更新 2

这是我得到的原始异常(当我不在调试模式下检查元素时)。

java.lang.NullPointerException
    at org.hibernate.envers.query.impl.EntitiesAtRevisionQuery.list(EntitiesAtRevisionQuery.java:72)
    at org.hibernate.envers.query.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:104)
    at org.hibernate.envers.entities.mapper.relation.OneToOneNotOwningMapper.mapToEntityFromMap(OneToOneNotOwningMapper.java:74)
    at org.hibernate.envers.entities.mapper.MultiPropertyMapper.mapToEntityFromMap(MultiPropertyMapper.java:118)
    at org.hibernate.envers.entities.EntityInstantiator.createInstanceFromVersionsEntity(EntityInstantiator.java:93)
    at org.hibernate.envers.entities.mapper.relation.component.MiddleRelatedComponentMapper.mapToObjectFromFullMap(MiddleRelatedComponentMapper.java:44)
    at org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor.addToCollection(ListCollectionInitializor.java:67)
    at org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor.addToCollection(ListCollectionInitializor.java:39)
    at org.hibernate.envers.entities.mapper.relation.lazy.initializor.AbstractCollectionInitializor.initialize(AbstractCollectionInitializor.java:67)
    at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.checkInit(CollectionProxy.java:50)
    at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.size(CollectionProxy.java:55)
    at <MY CODE HERE, which checks list.size()>

最终解决方案(实际上更多的是临时破解)

boolean worked = false;
while (!worked) {
    try {
        if(list.size() == 1) {
            // do stuff 
        }
        worked = true;
    } catch (Exception e) {
        // TODO: exception must be accessed or the loop will be infinite
        e.getStackTrace();
    }
}

【问题讨论】:

    标签: java eclipse hibernate debugging hibernate-envers


    【解决方案1】:

    好吧,你看到 Hibernate 的延迟加载在深度操作中发生了什么 :)

    基本上,hibernate 会为您延迟关联的关系加载代理类,这样您就可以获得一个 Hibernate 为您的 C 类自动生成的代理的 List(实际上是 PersistenceBag 实现),而不是类 C 的列表。这是 hibernate 延迟加载该关联的值直到它们被实际访问的方式。这就是为什么当您在 eclipse 调试器中访问它时(基本上是通过自省访问实例的字段/方法),您会看到 sql hibernate 触发器来获取所需的数据。

    这里的诀窍是,根据您访问惰性集合的时间,您可能会得到不同的结果。如果您使用 eclipse 调试器访问它,您更有可能仍在开始加载该事物的 Hibernate 会话中,因此一切都按预期工作,当访问该事物并加载数据时(懒惰地)触发 sql)。问题是,如果您想在代码中访问相同的数据,但在会话已经关闭的时候,您将获得 LazyInitializationException 或 null(如果您使用某些库来清理 put hibenrate 代理,则为后者)作为吉利德)

    【讨论】:

    • 失败的代码(抛出异常)就在我设置断点的地方,所以显然会话仍然有效,对吧?不同之处在于,如果我越过下一行,它就会爆炸,但如果我用 Eclipse 进行检查,那么越过下一行它就可以工作。
    • 我认为当eclipse调试器访问文件时也会发生错误,它只是由eclipse继续执行。当您不使用 Eclipse 进行调试/单步执行时,您得到的确切错误是什么?
    • 好点,没想到...我将例外附加到原始问题。
    • 事实证明 Eclipse 正在捕获您提到的异常,所以我最终做了与现在相同的解决方法(捕获异常、检查异常、重试)。
    • 看,不要成为一个无赖,但有时 Hibernate 只是有一些错误,表现为诸如此类的意外异常。尝试在休眠 jira 上查看您的异常:hibernate.onjira.com
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 2010-10-22
    • 2011-04-16
    相关资源
    最近更新 更多