开发者

p:dataList cannot iterate java.util.Set

I have a primefaces dataList within a primefaces dataGrid but I'm having issue mapping to a property of the nested dataList collection (java.util.Set). When I reference any attribute on the nested Set (dream.tag), I get exception:

javax.servlet.ServletException: /registered/modify.xhtml @42,48 value="#{tag.id}": Property 'id' not found on type org.hibernate.collection.PersistentSet.

That attribute is there, but the dream.tag attribute is mapped to a private Set tag. Is it possible to use the dataList component with a Set. I've copied an outline of my data model below. Thanks for the help!

<p:dataGrid var="dream" value="#{dreamModifyBean.dreams}" columns="5"  rows="10" paginator="true" effect="true"  paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="10,15,20" paginatorPosition="bottom"> 
    <p:column>  
        <h:panelGrid columns="1" style="width:100%"> 
            <h:outputText value="#{dream.order}. #{dream.title}"/><br/>
            <p:graphicImage value="#{dream.imageThumb}" width="125" height="100"/><br/>
            <h:outputText value="#{dream.notes}"/><br/>
            <p:dataList value="#{dream.tag}" var="tag">  
                <h:outputText value="#{tag.id}"/>
            </p:dataList> 
            <h:outputText value="#{bundle['dreamModify.cost.TEXT']} #{dream.cost}"/><br/>
        </h:panelGrid>  
    </p:column>  
</p:dataGrid>

Dream (dreamModifyBean.dreams) - Parent:

public class Dream implements Serializable{
 @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
 @JoinColumn(name="DREAM_ID")
 pr开发者_如何转开发ivate Set<Tag> tag;

public Set<Tag> getTag() {
    return tag;
}
public void setTag(Set<Tag> tag) {
    this.tag = tag;
}
}

Tag (dream.tag) - Child

public class Tag {
 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Basic(optional=false)
 @Column(name="ID")
 private Long id;
 @Basic(optional=false)
 @Column(name="DESCRIPTION")
 private String description;
 @ManyToOne(fetch=FetchType.EAGER)
 @JoinColumn(name="DREAM_ID")
 private Dream dream;

 public Long getId() {
    return id;
 }
 public void setId(Long id) {
    this.id = id;
 }
 public String getDescription() {
    return description;
 }
 public void setDescription(String description) {
    this.description = description;
 }
public Dream getDream() {
    return dream;
}
public void setDream(Dream dream) {
    this.dream = dream;
}
}


Try to use a List. The value attribute must be one of the following as described here:

  • a list of beans
  • an array of beans
  • a single bean
  • a javax.faces.model.DataModel object
  • a java.sql.ResultSet object
  • a javax.servlet.jsp.jstl.sql.Result object
  • a javax.sql.RowSet object


You can use toArray() method of the Set:

<p:dataList value="#{dream.tag.toArray}" var="tag">  
    <h:outputText value="#{tag.id}" />
</p:dataList>


I have exactly the same issue, and assume a bug in the primefaces implementation (it clearly states that it iterates over collections). BTW, it seems to fail while it renders the end tag, not the list itself.

A (not fully satisfying) workaround is to add a helper method:

public List<Tag> getTagsAsList() {
    return new ArrayList<Tag>(tags);
}

@Matt Handy: A Set can certainly be ordered, some implementations are (like TreeSet), others are not (like HashSet). The main difference between Set and List is the handling of duplicates.

Edit: I was too fast to blame Primefaces. Seems like the root of the problem lies in the JSF implementation itself, which is not providing a DataModel for Sets. See here for more details.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜