【问题标题】:p:dataList cannot iterate java.util.Setp:dataList 无法迭代 java.util.Set
【发布时间】:2011-03-11 01:49:59
【问题描述】:

我在 primefaces dataGrid 中有一个 primefaces dataList,但在映射到嵌套 dataList 集合 (java.util.Set) 的属性时遇到问题。当我引用嵌套集(dream.tag)上的任何属性时,我得到异常:

javax.servlet.ServletException: /registered/modify.xhtml @42,48 value="#{tag.id}": 在类型 org.hibernate.collection.PersistentSet 上找不到属性 'id'。

那个属性是存在的,但是dream.tag 属性被映射到一个私有的Set 标签。是否可以将 dataList 组件与 Set.我在下面复制了我的数据模型的大纲。感谢您的帮助!

<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>

梦想 (dreamModifyBean.dreams) - 家长:

public class Dream implements Serializable{
 @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
 @JoinColumn(name="DREAM_ID")
 private Set<Tag> tag;

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

标签 (dream.tag) - 孩子

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;
}
}

【问题讨论】:

    标签: java hibernate jsf primefaces


    【解决方案1】:

    尝试使用List。 value 属性必须是here 所述的以下属性之一:

    • bean 列表
    • 一组豆子
    • 一颗豆
    • 一个 javax.faces.model.DataModel 对象
    • 一个 java.sql.ResultSet 对象
    • 一个 javax.servlet.jsp.jstl.sql.Result 对象
    • javax.sql.RowSet 对象

    【讨论】:

    • 不错的清单。但是我想强调的是,使用ResultSetRowSet 是不好的做法(视图与数据库模型的耦合过于紧密,容易导致资源泄漏)。
    【解决方案2】:

    可以使用 Set 的 toArray() 方法:

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

    【讨论】:

      【解决方案3】:

      我有完全相同的问题,并假设在 primefaces 实现中有一个错误(它明确指出它会迭代集合)。顺便说一句,它似乎在呈现结束标记时失败,而不是列表本身。

      一个(不完全令人满意的)解决方法是添加一个辅助方法:

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

      @Matt Handy:一个集合可以当然是有序的,一些实现是(如 TreeSet),而另一些则不是(如 HashSet)。 Set 和 List 的主要区别在于对重复项的处理。

      编辑: 我太快了,不能责怪 Primefaces。似乎问题的根源在于 JSF 实现本身,它没有为 Sets 提供 DataModel。有关详细信息,请参阅here

      【讨论】:

      • 我认为如果你想依赖排序,你必须使用列表。 Set/List 问题之前已经讨论过。 See this question.
      • 这通常是不正确的(因为您链接到的讨论中的一些答案也在说明)。消除所有疑虑:看看TreeSet,它是一个具有明确定义的自然顺序的集合,您可以很好地依赖它。
      • 至于责备,Set 提供没有办法通过索引获取元素。这对于 JSF 来说只是强制性的,以便在应用请求值、验证、更新模型值和每当提交带有表的表单时调用应用程序阶段定位正确的行。
      • new ArrayList&lt;T&gt;(Set &lt;T&gt;) 将是一种方式 ;-) 当然,关于元素顺序的所有假设都取决于 Set 的实现,但也可能存在不需要一致排序的用例.在我看来,这将填补持久性(集合非常有用)和演示之间的空白。
      猜你喜欢
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 2019-03-26
      • 2018-07-18
      相关资源
      最近更新 更多