简体   繁体   English

当您检查变量时(调试时)eclipse会做什么?

[英]What does eclipse do when you inspect variables (while debugging)

I have an instance of org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy that is causing some grief: whenever I programmatically try to access it I get a null pointer exception (ie calling list.size() ) but when I first inspect the object using Eclipse's variable inspector I see Hibernate generate a SQL statement and the list changes dynamically. 我有一个org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy的实例,这引起了一些麻烦:每当我以编程方式尝试访问它时,我都会得到一个空指针异常(即,调用list.size() )但是当我第一次使用Eclipse的变量检查器检查对象时,我看到Hibernate生成了一条SQL语句,并且列表是动态变化的。 Then everything works. 然后一切正常。 How can I do the same thing programmatically? 我如何通过编程来做同样的事情? I've tried list.toString() but that doesn't seem to help. 我试过list.toString()但这似乎没有帮助。

Update 1 更新1

Don't know if this helps but when I first click on the list instance I see in the display: 不知道这是否有帮助,但是当我第一次单击列表实例时,我会在显示屏上看到:

com.sun.jdi.InvocationException occurred invoking method.

Then database query runs and when I click again I get the correct .toString() result. 然后运行数据库查询,当我再次单击时,我得到正确的.toString()结果。

Update 2 更新2

Here is the original exception I get (when I don't inspect the element in debug mode). 这是我得到的原始异常(当我不在调试模式下检查元素时)。

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()>

Final Solution (Actually more of a temporary hack) 最终解决方案(实际上更多是临时的hack)

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();
    }
}

Well what happends there is you're seing Hibernate's lazy loading in deep action :) 好吧,发生的事情是您在深度动作中抓住了Hibernate的延迟加载:)

Basically hibernate loads proxy classes for you lazily associated relations, such that instead of a List of classes C you get a List (actually a PersistenceBag implementation) of Hibernate autogenerated proxie for your C class. 基本上,hibernate为您的延迟关联关系加载代理类,这样,您可以获得C类的Hibernate自动生成的代理的列表(实际上是PersistenceBag实现),而不是类C的列表。 THis is hibernate's way of deferring load of that association's values until they are actually accessed. 这是休眠的方式,它将对该关联的值的加载推迟到实际访问它们之前。 So that's why when you access it in the eclipse debugger (which basically accesses an instance's fields/methids via introspection) you see the sql hibernate triggers to fetch the needed data. 因此,这就是为什么当您在Eclipse调试器(基本上是通过内省访问实例的字段/方法)中访问它时,您会看到sql休眠触发器触发来获取所需数据的原因。

The trick here is that depending on WHEN you access a lazy collection you might get different results. 这里的技巧是,取决于何时访问惰性集合,您可能会得到不同的结果。 If you access it using the eclipse debugger you're more likely still in the Hibernate session that started loading that thing, so everything works as expected, an sql is (lazily) triggered when the thing is accessed and the data is loaded). 如果使用eclipse调试器访问它,则很有可能仍处于开始加载该事物的Hibernate会话中,因此一切正常,在访问事物并加载数据时(懒惰地)触发了sql)。 Problem is that if you wanna access that same data in your code, but at a point where the session is already closed, you'll either get a LazyInitializationException or null (the latter if you're using some library for cleaning put hibenrate proxises such as Gilead) 问题是,如果您想在代码中访问相同的数据,但是在会话已经关闭的那一刻,您将得到LazyInitializationException或null(如果您正在使用某个库来清理hibenrate代理,则后者为null)。作为吉利德)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM