如何在渲染过程中发现异常时找到JSF组件?

时间:2015-08-12 17:41:38

标签: jsf jsf-2 lazy-initialization

环境:JBoss AS 7.2上的JSF 2.0,Seam 2.3,RF 4.3和PF 5

我在两个JSF页面上有一个奇怪的错误。我在渲染阶段得到一个LIE(延迟初始化异常)。

Error Rendering View[/secure/MyPage.xhtml]: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
    at com.mycompany.entity.Currency_$$_javassist_17.equals(Currency_$$_javassist_17.java) [:]
    at com.sun.faces.renderkit.html_basic.MenuRenderer.isSelected(MenuRenderer.java:724) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOption(MenuRenderer.java:550) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOptions(MenuRenderer.java:791) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.MenuRenderer.renderSelect(MenuRenderer.java:843) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.MenuRenderer.encodeEnd(MenuRenderer.java:297) [jsf-impl-2.1.29.jar:2.1.29]
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877) [jsf-api-2.1.29.jar:2.1]
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129) [jsf-impl-2.1.29.jar:2.1.29]
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) [jsf-api-2.1.29.jar:2.1]
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:447) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.29.jar:2.1.29]
    at org.jboss.seam.jsf.SeamViewHandler.renderView(SeamViewHandler.java:188) [jboss-seam.jar:2.3.1.Final]
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:286) [jsf-api-2.1.29.jar:2.1]
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.1.29.jar:2.1.29]
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.29.jar:2.1.29]

有问题的网页开始新的对话,不应该有任何陈旧的对话。大多数情况下这些页面工作正常,但偶尔他们会开始抛出此异常并继续抛出该异常,直到您再次注销为止。

所以我只能假设有一些东西引用了Session scoped bean中的实体。

但问题是它们在哪里被引用以及引用了什么?

有没有办法找出导致异常的组件(ID或哪个行/文件)?否则就是在一个相当大的草堆中寻找针头。是否可能需要启用某个记录器类别(设置为DEBUG或TRACE)?

我已经尝试排除页面的较大部分以缩小问题范围,但即使我再次添加以前删除的部分,页面也会突然再次运行。所以一个适当的Heisenbug; - (

2 个答案:

答案 0 :(得分:1)

错误清楚地表明在jsf页面中呈现Menu组件期间发生了异常,即xhtml。

 at com.sun.faces.renderkit.html_basic.MenuRenderer.isSelected(MenuRenderer.java:724)

答案 1 :(得分:1)

已经可以基于堆栈跟踪单独解释很多(如果必要的话,阅读相关的源代码,如果你不能理解类和方法名称)。

根据堆栈跟踪,当MenuRenderer忙于呈现<option>元素并通过项目值的equals()方法确定是否应设置selected时,会发生这种情况预选的原因。此渲染器仅由<h:select(One|Many)(Menu|Listbox)>组件使用。它恰好是com.mycompany.entity.Currency实例代表<f:selectItems><h:selectMany(Menu|Listbox)>的单个项目值的组件,如此value="#{someBean.someEntity.currencies}"

显然,使用Collection<Currency>代替FetchType.LAZY提取FetchType.EAGER。因此,Hibernate需要加载它,但不能这样做,因为在JSF渲染响应阶段,DB会话无处可用。它仅在事务感知服务方法中可用,例如EJB方法。换句话说,您的数据预加载逻辑是错误的,应该更改为使用FetchType.EAGER代替获取Collection<Currency>之前JSF可以使用该数据呈现菜单。

另见: