看来,如果您使用由hibernate代理的集合支持的selectManyCheckbox,您将遇到可怕的LazyInitializationException问题。这与支持bean的状态无关!
在调试Mojarra 2.1之后,我发现如果不包含属性collectionType,它将在流程验证阶段尝试克隆支持的值类,在我的例子中是PersistentSet。当然,给它添加任何值都会导致LazyInitializationException。
我的问题是,您是否认为这是过程验证阶段的合理行为?
克隆集合类的更好的算法是查看接口并从java.util实例化一个已知的类。
这正是问题的关键!它与会话状态无关…我遇到了这个问题,我能够通过在我的组件中添加以下内容(在我的情况下是selectManyMenu)来解决这个问题:
<f:attribute name="collectionType" value="java.util.ArrayList" />;
感谢您对h:selectMany标签使用collectionType属性来防止LazyInitializationException的提示。
然而,与其在一个不合适的论坛上怒骂它,不如了解一下JSF 2.0的新特性,并发布一个完整的问题示例以及如何修复它?
基础:
- Mojarra 2.1是JSF 2的参考实现(参见Mojarra是什么)
- h:selectManyCheckbox VLD文档描述了如何使用collectionType属性(在JSF 2.0中新增)
- 这个问题影响h:selectManyCheckbox, h:selectManyListBox和h:selectManyMenu标签的验证
这个错误的堆栈跟踪:
Feb 04, 2013 1:20:50 PM com.sun.faces.lifecycle.ProcessValidationsPhase execute警告:惰性初始化集合失败,没有会话或会话已关闭lazyinitializationexception:惰性初始化集合失败,没有会话或会话已关闭org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException (AbstractPersistentCollection.java: 383)org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected (AbstractPersistentCollection.java: 375)org.hibernate.collection.AbstractPersistentCollection.readSize (AbstractPersistentCollection.java: 122)org.hibernate.collection.PersistentBag.isEmpty (PersistentBag.java: 255)javax.faces.component.UIInput.isEmpty (UIInput.java: 1257)javax.faces.component.UIInput.validateValue (UIInput.java: 1144)javax.faces.component.UISelectMany.validateValue (UISelectMany.java: 579)
添加collectionType来修复此错误的示例(我使用自定义验证器):
<h:selectManyListbox value="${technologyService.entity.associatedLabs}"
collectionType="java.util.ArrayList">
<f:validator validatorId="selectManyListboxValidator" />
<f:attribute name="maxItems" value="5" />
<f:selectItems value="${metadataService.activeLabSelectItems}" />
</h:selectManyListbox>