懒惰加载时PrimeFaces DataTable中的奇怪行为(Video inside;))

时间:2014-04-03 18:59:47

标签: java java-ee jsf-2 primefaces datatable

晚上来自德国!

我对PrimeFaces DataTable组件有一个非常奇怪的行为:

我有一个简单的pojo,一个从DB中获取POJO的EJB,一个用于我的JSF页面的Controller和一个从Primefaces实现LazyDataModel的CDI Bean。一切都按预期工作。站点之间的分页工作,过滤器和排序。但是当我使用ActionListener单击DataTable-Row中的Button时,一切都停止了。在重新加载页面之前,分页不起作用(请求/响应已完成......非常奇怪)。

我制作了一个视频以便更好地理解:

https://www.youtube.com/watch?v=B2PgQCNIVQc

我想,EJB调用一定是问题,但我错了。我用一个简单的ArrayList做了一点(非常快速和肮脏;))示例,我能够重现这个(Primefaces 4.0.x& Primefaces 5-Snapshot):

起初,我的POJO:

public class User {
  private String login;
  private Date removeDate;

  public String getLogin() {
    return login;
  }

  public void setLogin(String login) {
    this.login = login;
  }

  public Date getRemoveDate() {
    return removeDate;
  }

  public void setRemoveDate(Date removeDate) {
    this.removeDate = removeDate;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User)) return false;

    User user = (User) o;

    if (!login.equals(user.login)) return false;

    return true;
  }

  @Override
  public int hashCode() {
    return login.hashCode();
  }
}

使用LazyLoad-Method和Action:

的非常简单的ControllerBean
@Named
@SessionScoped
public class LazyUserBean implements Serializable {

  private List<User> userEntityList = new ArrayList<>();

  @PostConstruct
  public void init() {
    for (int i = 0; i < 100; i++) {
      User newUser = new User();
      newUser.setLogin("User " + i);
      newUser.setRemoveDate(new Date());

      userEntityList.add(newUser);
    }
  }

  public List<User> getAllEntitiesLazy(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters, boolean invalidate) {
    List<User> returnList = new ArrayList<>();

    for (int i = first; i < this.userEntityList.size(); i++) {
      returnList.add(this.userEntityList.get(i));
    }
    return returnList;
  }

  public void removeDelDate(User user) {
    user.setRemoveDate(null);
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
        Environment.getMessageResourceString("de.flatphormesmedia.wbsagentur.resources.lang_de", "persistence.recycleSuccess", new String[]{"bla"}), ""));
  }
}

LazyLoadModel-Implementation:

@Named
@ViewScoped
public class LazyUserModel extends LazyDataModel<User> implements Serializable {
  private List<User> datasource;

  @Inject
  LazyUserBean lazyUserBean;

  @Override
  public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
    this.datasource = this.lazyUserBean.getAllEntitiesLazy(first, pageSize, sortField, sortOrder, filters, true);
    this.setRowCount(100);

    return datasource;
  }

  @Override
  public Object getRowKey(User user) {
    return user.getLogin();
  }
}

最后是JSF页面:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://primefaces.org/ui ">
<h:head>
</h:head>
<h:body>
    <h:form id="formEditUsers">
        <p:dataTable value="#{lazyUserModel}" var="user" lazy="true" paginator="true"
                     rows="13" id="tableUsers" emptyMessage="#{langRes['editUsers.emptyTable']}"
                     paginatorPosition="top">
            <!-- user login column -->
            <p:column headerText="#{langRes['editUsers.colHeadLogin']}" id="columnLogin"
                      filterBy="#{user.login}"
                      sortBy="#{user.login}">
                <p:outputLabel id="labelLogin" value="#{user.login}"/>
            </p:column>
            <!--delete date column-->
            <p:column headerText="#{langRes['setupAddresses.colHeadDeleteDate']}" id="columnDeletedDate"
                      width="20%">
                <p:outputLabel id="labelDeletedDate" value="#{user.removeDate}">
                    <f:convertDateTime pattern="dd.MM.yyyy - HH:mm:ss"/>
                </p:outputLabel>
            </p:column>

            <!-- edit column -->
            <p:column id="columnEdit" width="10%" style="text-align: center">
                <p:commandButton actionListener="#{lazyUserBean.removeDelDate(user)}"
                                 update=":formEditUsers:tableUsers"
                                 process="@this" id="buttonRecycle" icon="ui-icon-arrowreturnthick-1-w"
                                 style="height: 70% !important">
                </p:commandButton>
            </p:column>
        </p:dataTable>
    </h:form>
</h:body>
</html>

正如我所说,非常快速和肮脏...但这里没什么特别的。自上周六以来,它让我疯狂。我在这里做错了什么?或者这是PrimeFaces-Bug?无法相信,我是第一个发现这种行为的人。 提前谢谢!

更新1:我在CommandButton中添加了ajax =“false”属性,并且在完整请求下它的工作方式就像一个魅力。按钮有什么问题吗?

3 个答案:

答案 0 :(得分:1)

这是一个主要的错误。使用r11009(https://code.google.com/p/primefaces/source/detail?r=11009)修复。

答案 1 :(得分:0)

好吧,我以前从未见过LazyDataModel也是一个托管bean。你的代码看起来不错,所以也许你应该尝试将模型和bean分成不同的类。

答案 2 :(得分:0)

请尝试process =&#34;:formEditUsers:tableUsers&#34;而不是进程=&#34; @ this&#34;