2

我有一个导致一些悲伤的实例:org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy每当我以编程方式尝试访问它时,我都会得到一个空指针异常(即调用list.size()动态的。然后一切正常。我怎样才能以编程方式做同样的事情?我试过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();
    }
}
4

1 回答 1

4

好吧,发生了什么,您正在深入了解 Hibernate 的延迟加载 :)

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

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

于 2011-09-21T17:26:42.167 回答