【问题标题】:How to find JSF component when there is an exception during rendering?渲染过程中出现异常如何查找JSF组件?
【发布时间】:2015-08-12 17:41:38
【问题描述】:

环境: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]

相关页面开始了新的对话,其中不应有任何陈旧的内容。大多数情况下,这些页面运行良好,但偶尔会开始抛出此异常,并且会继续抛出异常,直到您注销并再次登录。

所以我只能假设某些东西正在引用会话范围 bean 中的实体。

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

有没有办法找出哪个组件(ID 或哪个行/文件)导致了异常?否则就是大海捞针。是否可能需要启用某个记录器类别(设置为 DEBUG 或 TRACE)?

我尝试排除页面的较大部分以缩小问题范围,但即使我再次添加之前删除的部分,页面也会突然恢复正常。所以一个合适的 Heisenbug ;-(

【问题讨论】:

  • 把组件的手册id放上,而不是JSF自己生成的ID。

标签: jsf jsf-2 lazy-initialization


【解决方案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 需要加载它,但由于 DB 会话在 JSF 渲染响应阶段不可用,因此无法加载。它仅在事务感知服务方法中可用,例如 EJB 方法。换句话说,您的数据预加载逻辑是错误的,应该更改为使用FetchType.EAGER,而不是在JSF 可以使用该数据呈现菜单之前获取Collection<Currency>

另见:

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2014-09-25
      • 2013-08-12
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多