我在这两个实体之间建立了多对多关系,分别称为事件和艺术家,它们都被注释为延迟加载。加载艺术家时,我会初始化其事件,因为此后该会话将使用关闭
Hibernate.initialize(artist.getEvents());
用纯Java进行的测试工作正常,之后我可以访问事件及其属性。
但是在显示结果的.xhtml页面中,我只能访问artist的属性并测试是否有任何可用事件,Artist是后备bean,getData()返回Artist,以下行仍然有效:
<h:outputText value="No events available" rendered="#{empty artist.data.events}"/>
但是当我想使用以下方法访问dataTable中事件的属性时
<h:dataTable value="#{artist.data.events}" var="event" rendered="#{not empty artist.data.events}">
<h:column>
<h:outputText value="#{event.title}"/>
</h:column>
</h:dataTable>
我得到了Followig异常:
/artist.xhtml @48,63 value="#{event.title}": The class 'org.hibernate.collection.PersistentSet' does not have the property 'title'.
我首先想到的是Hibernate的initialize方法不能与JSF2一起使用,但是当我将FetchType从LAZY更改为EAGER时,最终得到了相同的结果。
Event类看起来像这样,为简洁起见,我只包括了与title属性相关的部分:
@Entity()
@Table(name="Events")
@SequenceGenerator(name="events_id", sequenceName="event_seq", initialValue=1, allocationSize=1)
public class EventData implements Serializable {
private String title;
// other private variables
public EventData() {}
public EventData(String title, ...) {
this.title = title;
// ...
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
// other setters/getters, equals/getHashCode overrides
}
最佳答案
UIData
组件只能在T[]
,List<E>
或DataModel<E>
上进行迭代,而不能在Set<E>
上进行迭代,因为无法通过索引在Set<E>
中标识元素,而在UIData
组件。
@Bozho写了weblog描述了一种解决方法。其他方法是将JPA配置为使用List<E>
或添加将其包装在List<E>
或DataModel<E>
中并在UIData
组件中使用的getter。例如。
public DataModel<Event> getEventModel() {
return new ArrayDataModel<Event>(events.toArray(new Event[events.size()]));
}
顺便说一下,这使用相同的实例(不会复制/克隆/重新创建它们),因此所有更改都将反映在正确的实例中。
更新:在即将发布的JSF 2.2中,
UIData
最终将为support Collection<E>
,因此将包括Set<E>
。另一种方法是创建一个自定义的EL解析器,如下所示:How do I use a java.util.Set with UIData in JSF. Specifically h:datatable?