我有一个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();
}
}
答案 0 :(得分:4)
那里发生的事情是你在深层行动中看到Hibernate的延迟加载:)
基本上,hibernate会为你的懒惰关联关系加载代理类,这样你就可以获得C类的Hibernate自动生成代理的List(实际上是PersistenceBag实现),而不是类C的List。这是hibernate推迟加载该关联值的方法,直到实际访问它们为止。这就是为什么当你在eclipse调试器(基本上通过内省访问实例的字段/方法)访问它时,你会看到sql hibernate触发器来获取所需的数据。
这里的诀窍在于,根据您何时访问惰性集合,您可能会得到不同的结果。如果你使用eclipse调试器访问它,你很可能仍然在开始加载那个东西的Hibernate会话中,所以一切都按预期工作,当访问东西并加载数据时,(懒惰)触发sql)。问题是,如果你想在你的代码中访问相同的数据,但是在会话已经关闭的时候,你将得到一个LazyInitializationException或null(后者如果你使用一些库来清理put hibenrate proxises等作为基列)