我有一个 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
这是我得到的原始异常(当我不在 Debug模式下检查元素时)。
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();
}
}
最佳答案
发生的事情是,您正在深入了解 Hibernate 的延迟加载:)
基本上,hibernate 会为您的延迟关联关系加载代理类,这样您就可以获得 C 类的 Hibernate 自动生成代理的列表(实际上是 PersistenceBag 实现),而不是类 C 的列表。这是 hibernate 推迟加载关联值直到实际访问它们的方法。这就是为什么当您在 Eclipse 调试器中访问它时(它基本上通过内省(introspection)访问实例的字段/方法),您会看到 sql hibernate 触发器来获取所需的数据。
这里的技巧是,根据您访问惰性集合的时间,您可能会得到不同的结果。如果您使用 eclipse 调试器访问它,您很可能仍在开始加载该事物的 Hibernate session 中,因此一切都按预期工作,当访问事物并加载数据时会(延迟)触发 sql)。问题是,如果您想在代码中访问相同的数据,但在 session 已经关闭的情况下,您将得到 LazyInitializationException 或 null(如果您使用某些库来清理放置 hibenrate 代理,则后者为空)作为吉利德)
关于java - 当您检查变量(调试时)时,Eclipse 会做什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7503217/