无法从JSF2访问延迟注释但初始化的hibernate集合

时间:2010-07-11 10:19:24

标签: java hibernate jsf jsf-2

我在称为事件和艺术家的两个实体之间存在多对多关系,两者都注释为延迟加载。当我加载艺术家时,我会初始化其事件,因为会话将在之后使用

关闭
Hibernate.initialize(artist.getEvents());

纯Java中的测试工作正常,之后我可以访问事件及其属性。

但是在显示结果的.xhtml页面中,我只能访问艺术家的属性并测试是否有可用的事件,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>

我得到了关注例外:

/artist.xhtml @48,63 value="#{event.title}": The class 'org.hibernate.collection.PersistentSet' does not have the property 'title'.

我的第一个想法是Hibernate的初始化方法不能与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    

}

2 个答案:

答案 0 :(得分:6)

UIData个组件只能迭代T[]List<E>DataModel<E>,而不是Set<E>,因为没办法通过索引标识Set<E>中的元素,而UIData个组件则需要该元素。

@Bozho撰写了一篇weblog来描述如何解决这个问题的方法。其他方法是将JPA配置为使用List<E>,或者添加一个将其包装在List<E>DataModel<E>中的getter,并在UIData组件中使用它。 E.g。

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?

答案 1 :(得分:0)

Voodoo需要将任何bean暴露给#{...}工具。最简单的方法是在Web容器支持CDI时使用CDI,否则请查看JSF2中的@ManagedBean批注。