1

在支持 beanedit()方法中,我有以下代码

public void edit(Entity e) {
    this.entity = entityService.find(e);
    this.entity.setLazyList(new ArrayList(this.entity.getLazyList()));
}
public Entity getEntity() {
    return this.entity;
}

如图所示,我通过用自己的ArrayList. 奇怪的是,内部惰性列表一存在方法PersistentBag就会返回edit()。我做了什么来发现这种行为:

  1. 在编辑方法中放置一个断点。找到后,我看到已创建实体的 JVM ID,说它是 101。
  2. 在方法中设置一个断点getEntity()edit()存在后被getEntity()调用,实体的JVM ID还是101,但是entity.lazyListPersistentBag而不是ArrayList

我的 LazyList 绑定到 . 然后,当我在 JSF 页面中按下保存按钮时,此 PersistentBag 会导致 LazyInitializationException。抛出异常(在调用支持 bean 中的 save() 方法之前)因为来自 Mojarra 的这一部分(也用 MyFaces 测试,它也抛出异常):

菜单渲染器,行:365

// No cloned instance so if the modelType happens to represent a
// concrete type (probably not the norm) try to reflect a
// no-argument constructor and invoke if available.
if (targetCollection == null) {
    //noinspection unchecked
    targetCollection =
          createCollection(currentValue, modelType);
}

由于currentValue不幸的是 PersistentBag(并且也已初始化),因此 createCollection() 返回此对象的新实例,该实例不再知道会话和加载的对象。

4

1 回答 1

0

刚刚添加<f:attribute name="collectionType" value="java.util.ArrayList" />到我<h:selectManyCheckBox>的里面,懒惰的异常就解决了。不再需要使用 ArrayList 手动更改 PersistentBag:

this.entity.setLazyList(new ArrayList(this.entity.getLazyList()));

此属性(适用于 Mojarra 和 MyFaces)告诉 JSF impl 使用此集合类型而不是绑定到元素的原始类型:

<h:selectManyCheckbox value="#{backingBean.entity.lazyList}">
     <f:attribute name="collectionType" value="java.util.ArrayList" />
     <f:selectItems value="#{backingBean.allItems}" var="i" itemLabel="#{i.title}"/>
</h:selectManyCheckbox>
于 2012-12-27T05:26:38.510 回答