Primefaces inplace编辑器内部动态加载p:accordionPanel在编辑时重新排序ArrayList

时间:2014-02-20 14:19:10

标签: java jsf primefaces arraylist

我正在使用PrimeFaces 4.0将注释列表加载到对话框中的动态数量的p:accordionPanel选项卡中。当用户单击p:datatable的行时,将打开该对话框。此列表的类型为ArrayList< Note >NoteNotes SQL表的enitity bean。 Notes表与@ManyToOne表格具有Users关系。

在每个p:accordionPanel标签中,我使用p:inplacep:calendarp:selectManyCheckbox为每个笔记设置各种参数。

我对p:calendarp:selectManyCheckbox代码没有任何问题。

但是,当我使用p:inplace编辑参数时,它似乎会更改Note中包含的ArrayList个对象的顺序。 因此,当我关闭并重新打开对话框时,已编辑的笔记已移至accordionPanel中的新位置。

我已确认ArrayList中的对象已通过调用description中第一个Note对象的ArrayList参数重新排序,使用以下代码在p:accordionPanel

<h:outputText value="Description: " />
<h:outputText value="#{userDAO.notes.get(0).description}" />

JSF HTML页面的相关代码段是:

<p:accordionPanel id="accordionPanelNotes"
    value="#{userDAO.visits}"
    var="accordionNotesList" multiple="true"
    activeIndex="0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20">

    <p:tab title="#{accordionNotesList.dateTime}"
    id="tabTitleNotes">
        <h:outputText value="Description: *" />
        <h:outputText value="#{userDAO.notes.get(0).description}" />

    <h:panelGrid columns="2" cellpadding="10">
        Description:
        <p:inplace emptyLabel="--empty--"
            id="ajaxInplaceNotesDescription" editor="true">
            <p:ajax event="save"
                listener="#{userDAO.handleEditSave}"
                update="accordionPanelNotes" oncomplete="updateNotesTable()"/>
            <p:inputText value="#{accordionNotesList.description}"
                required="true" label="text" />
        </p:inplace>

        ...

</p:accordionPanel>


userDAO.handleEditSave()方法:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void handleEditSave() throws SecurityException,
        IllegalStateException, RollbackException, HeuristicMixedException,
        HeuristicRollbackException, NamingException, NotSupportedException,
        SystemException {

    utx.begin();

        User user = (User) em.find(User.class, this.selectedUserRow.getId());

        user.setNotes(this.selectedUserRow.getNotes());

        em.merge(user);

    utx.commit();

}

Note的getter和setter:

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Note> notes = new ArrayList<Note>();

public List<Note> getNotes() {
    return this.getNotes();
}

public void setNotes(List<Note> notes) {
    this.setNotes(notes);
}

我能想到的唯一可能导致此行为的是,如果来自user.setNotes(this.selectedUserRow.getNotes())方法的行handleEditSave()以某种方式使命令混乱。

可能导致ArrayList内对象的顺序发生变化的原因是什么?

1 个答案:

答案 0 :(得分:0)

在我的代码中像机枪(!)一样触发System.out.println()方法后,我得出的结论是,当列表中的实体bean中的参数发生更改时,列表不一定是相同的顺序就像改变之前一样。进一步的Google搜索提出了将注释@OrderBy添加到List< Note >模型中的User声明的解决方案,如下所示:

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OrderBy
private List<Note> notes = new ArrayList<Note>();

这将强制列表填充由数据库中的主键排序的Note个对象。

在我的情况下,我很幸运,在第一次加载时,列表已按数据库行的顺序填充,这与主键顺序的行相对应。

还可以使用注释@OrderBy("nameOfAnotherColumn")

强制列表按主键以外的列排序