hibernate - RESTORE_VIEW 中的 LazyInitializationException(PersistentSet 实例化不正确)

标签 hibernate jsf jpa drag-and-drop icefaces

我正在开始使用 IceFaces,但在尝试拖放支持时遇到了问题。

IceFaces 2.0.0
JSF 2.0
Mojarra 2.0.2 (FCS b10) (JSF reference implementation)
Spring 3.0.3
Hibernate 3.5.1-Final
JPA 2.0 (with OpenEntityManagerInViewFilter)

问题是删除时的LazyInitializationException。我的第一个结论是持久性上下文生命周期管理设置不正确,但是经过几个小时的设置、依赖项和调试后,我发现了奇怪的事情:JSF 实现正在创建 PersistentSet 实例通过在 RESTORE_VIEW 阶段使用默认构造函数 (!) 进行反射并尝试向其中添加值。此操作会导致 LazyInitializationException,因为 PersistentSet 是作为 ArrayList 等简单集合创建的,并且未正确配置(未设置 session )。

org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException
                                        (AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected
                                        (AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    at org.hibernate.collection.PersistentSet.add(PersistentSet.java:212)
    at javax.faces.component.UIComponentBase.restoreAttachedState(UIComponentBase.java:1582)
    at javax.faces.component.ComponentStateHelper.restoreState(ComponentStateHelper.java:290)
    at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1444)
    at com.icesoft.faces.component.panelseries.UISeries.restoreState(UISeries.java:642)
    at com.icesoft.faces.component.panelseries.PanelSeries.restoreState(PanelSeries.java:138)
    at com.sun.faces.application.view.StateManagementStrategyImpl$2.visit(StateManagementStrategyImpl.java:231)
    at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:147)
    at com.icesoft.faces.component.panelseries.UISeries.visitTree(UISeries.java:814)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
    at javax.faces.component.UIForm.visitTree(UIForm.java:333)
    at com.icesoft.faces.component.panelseries.UISeries.visitColumnsAndRows(UISeries.java:898)
    at com.icesoft.faces.component.panelseries.UISeries.visitTree(UISeries.java:832)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
    at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:223)
    at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:177)
    at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:131)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:430)
    at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:143)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:199)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
javax.faces.FacesException: Unexpected error restoring state for component with id castle-list:j_idt12:castle-resident-list.  
Cause: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed.
    at com.sun.faces.application.view.StateManagementStrategyImpl$2.visit(StateManagementStrategyImpl.java:239)
    at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:147)
    at com.icesoft.faces.component.panelseries.UISeries.visitTree(UISeries.java:814)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
    at javax.faces.component.UIForm.visitTree(UIForm.java:333)
    at com.icesoft.faces.component.panelseries.UISeries.visitColumnsAndRows(UISeries.java:898)
    at com.icesoft.faces.component.panelseries.UISeries.visitTree(UISeries.java:832)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
    at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:223)
    at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:177)
    at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:131)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:430)
    at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:143)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:199)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.LazyInitializationException: 
                    failed to lazily initialize a collection, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException
                                        (AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected
                                        (AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    at org.hibernate.collection.PersistentSet.add(PersistentSet.java:212)
    at javax.faces.component.UIComponentBase.restoreAttachedState(UIComponentBase.java:1582)
    at javax.faces.component.ComponentStateHelper.restoreState(ComponentStateHelper.java:290)
    at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1444)
    at com.icesoft.faces.component.panelseries.UISeries.restoreState(UISeries.java:642)
    at com.icesoft.faces.component.panelseries.PanelSeries.restoreState(PanelSeries.java:138)
    at com.sun.faces.application.view.StateManagementStrategyImpl$2.visit(StateManagementStrategyImpl.java:231)
    ... 34 more

JSF实现库的这段代码存在问题:

(javax/faces/component/UIComponentBase.java:1566-1591):

if (stateObj instanceof List) {
    List<StateHolderSaver> stateList = (List<StateHolderSaver>) stateObj;
    Collection<Object> retCollection = null;
    StateHolderSaver collectionSaver = stateList.get(0);
    Class collectionClass = (Class) collectionSaver.restore(context);
    try {
        retCollection = (Collection<Object>) collectionClass.newInstance();     //(*)
    }
    catch (Exception e) {
        if (LOGGER.isLoggable(Level.SEVERE)) {
            LOGGER.log(Level.SEVERE, e.toString(), e);
        }
        throw new IllegalStateException("Unknown object type");
    }
    for (int i = 1, len = stateList.size(); i < len; i++) {
        try {
            retCollection.add(stateList.get(i).restore(context));       //(**)
        } catch (ClassCastException cce) {
            if (LOGGER.isLoggable(Level.SEVERE)) {
                LOGGER.log(Level.SEVERE, cce.toString(), cce);
            }
            throw new IllegalStateException("Unknown object type");
        }
    }
    result = retCollection;
}
  • * 在我的例子中,“collectionClass”是“org.hibernate.collection.PersistentSet”。
  • ** “retCollection.add”调用结果 LazyInitializationException

简单的maven项目即可downloaded here 。只需将其作为网络应用程序运行,在“英雄”和“城堡”部分中创建一些条目,然后尝试通过在“城堡与英雄”部分中的拖放来绑定(bind)它们。

尚不清楚谁应对此问题负责 - JSF RI、IceFaces 还是我的手=) 我已在 IceFaces 和 Oracle 论坛上发布了此问题:

http://www.icefaces.org/JForum/posts/list/18539.page
http://forums.oracle.com/forums/thread.jspa?messageID=9328036

请告诉我一些解决方法或指出我的错误=)

最佳答案

我在 primefaces p:selectManyCheckbox 组件上遇到了类似的问题。 也许不完全是你的情况,但添加 f:attribute name="collectionType" 到组件可以解决问题。

<p:selectManyCheckbox value="#{offerEditBean.selectedFloors}" converter="ait.entity.converter" layout="pageDirection">
    <f:attribute name="collectionType" value="java.util.HashSet" />
    <f:selectItems value="#{offerEditBean.floors}" var="item" itemValue="#{item}" itemLabel="#{item.name}" />
</p:selectManyCheckbox>

仅供引用:实例变量 selectedFloors 从实体 @OneToMany 设置属性初始化。

所以,回答你的问题,这主要是一个 JSF 问题。

我在这里找到了这个解决方案http://forum.primefaces.org/viewtopic.php?f=3&t=30765

关于hibernate - RESTORE_VIEW 中的 LazyInitializationException(PersistentSet 实例化不正确),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4855672/

相关文章:

hibernate - session.clear() 如何在 Hibernate 中工作

jsf - 在jsf页面中使用ckeditor

hibernate - JPA原生查询结果返回重复的子对象

hibernate - 是否有注释在jpa2中定义多列索引

java - 添加到集合中时,类不会保留新的关联对象

java - hibernate中的单表策略继承

hibernate 异常 : Connection Pool exhausted error after Spring upgrade

javascript - 无法调用 JS 进行验证 (JSF)

JSF 生命周期示例

java - 覆盖子类实体中@MappedSuperclass 的继承属性(例如继承关系表名、列名...等)