Функция dataTable sortBy не работает (простые лица)

У меня проблема с компонентом dataTable. Я не знаю, почему он не сокращает данные в таблице, когда я нажимаю на нее.

<p:dataTable var="garbage" value="#{resultsController.allGarbage}" dynamic="true" paginator="true" paginatorPosition="bottom" rows="10"  
             paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"  
             rowsPerPageTemplate="5,10,15">         

            <p:column sortBy="#{garbage[0].filename}">  
            <f:facet name="header">  
            <h:outputText value="Filename" />  
            </f:facet>  
            <h:outputText value="#{garbage[0]}" />
             </p:column> 

            <p:column>  
            <f:facet name="header">  
            <h:outputText value="Description" />  
            </f:facet>  
            <h:outputText value="#{garbage[1]}" />  
             </p:column> 

            <p:column sortBy="#{garbage[2].uploadDate}">  
            <f:facet name="header">  
            <h:outputText value="Upload date" />  
            </f:facet>  
            <h:outputText value="#{garbage[2]}" /> 
             </p:column>                
    </p:dataTable> 

Это управляемый компонент

@ManagedBean
@RequestScoped
public class ResultsController {

@EJB
private ISearchEJB searchEJB;

private Garbage[] garbage;

public List<Garbage[]> getAllGarbage() {
    return searchEJB.findAllGarbage();
}

public Garbage[] getGarbage() {
    System.out.println("VALUES!!!!!!!!" + garbage[0].getFilename());
    return garbage;
}

public void setGarbage(Garbage[] garbage) {
    this.garbage = garbage;
}

}

Это EJB, который разрешает доступ к данным

@Stateless(name = "ejbs/SearchEJB")

открытый класс SearchEJB реализует ISearchEJB {

@PersistenceContext
private EntityManager em;


public List<Garbage[]> findAllGarbage() {
    Query query = em.createNamedQuery("findAllGarbage");        
    return  query.getResultList();
}

}

И это сущность (представление данных)

@NamedQuery(name = "findAllGarbage", query = "SELECT g.filename, g.description,  g.uploadDate FROM Garbage g;")
    @Entity
    public class Garbage {
@Id
@GeneratedValue
@Column(nullable = false)
private Long id;
@Column(nullable = false)
private String filename;
@Column(nullable = false)
private String fileType;
@Column(nullable = false)
private String uploadDate;
@Column(nullable = false)
private String destroyDate;
@Lob
@Column(nullable = false)
private byte[] file;
@Column(nullable = false)
private String description;
...//Getters and Setters

Как показано на изображении, при нажатии кнопок сортировки изменений нет: введите здесь описание изображения

Вот что говорит консоль:

СЕРЬЕЗНО: ошибка сортировки

ОБНОВЛЕНИЕ

public List<Garbage> findAllGarbage() {
    Query query = em.createNamedQuery("findAllGarbage");    

    List<Garbage> gList = new ArrayList();

    for (Object o: query.getResultList()) {         
      Garbage tmpG = new Garbage();
      tmpG.setFilename(((Garbage) o).getFilename());          
      tmpG.setUploadDate(((Garbage) o).getUploadDate());
      tmpG.setDescription(((Garbage) o).getDescription());

      gList.add(tmpG);
    }
    return  gList;
}

Модифицированный управляемый компонент

@ManagedBean
@RequestScoped
public class ResultsController {

@EJB
private ISearchEJB searchEJB;

private Garbage garbage;

public List<Garbage> getAllGarbage() {
    return searchEJB.findAllGarbage();
}

public Garbage getGarbage() {
    return garbage;
}

public void setGarbage(Garbage garbage) {
    this.garbage = garbage;
}   

}

Модифицированный JSF

<p:dataTable var="garbage" value="#{resultsController.allGarbage}" dynamic="true" paginator="true" paginatorPosition="bottom" rows="10"  
             paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"  
             rowsPerPageTemplate="5,10,15">         

            <p:column sortBy="#{garbage.filename}" parser="string">  
            <f:facet name="header">  
            <h:outputText value="Filename" />  
            </f:facet>  
            <h:outputText value="#{garbage.filename}" />
             </p:column> 

            <p:column>  
            <f:facet name="header">  
            <h:outputText value="Description" />  
            </f:facet>  
            <h:outputText value="#{garbage.description}" />  
             </p:column> 

            <p:column sortBy="#{garbage.uploadDate}" parser="string">  
            <f:facet name="header">  
            <h:outputText value="Upload date" />  
            </f:facet>  
            <h:outputText value="#{garbage.uploadDate}" /> 
             </p:column>                
    </p:dataTable> 

person javing    schedule 29.03.2011    source источник
comment
Я не понимаю, что вы пытаетесь сделать. У вас есть список массивов, и ваша таблица будет печатать строковое представление экземпляра Garbage в каждой ячейке. Немного больше информации о вашей структуре данных поможет (возможно).   -  person Matt Handy    schedule 29.03.2011
comment
Я только что обновил и добавил, как выглядит EJB, а также Entity Garbage. Надеюсь, это поможет вам понять. Может быть, мне нужно добавить какой-либо тег сценария в тег заголовка? Я не понимаю, почему он не работает.   -  person javing    schedule 29.03.2011
comment
Я нашел кое-что интересное в этом руководстве на странице 94 web-cinema.googlecode.com/files/primefaces_users_guide_140210.pdf. Это руководство Primefaces. В нем говорится, что если моя таблица данных является динамической, я должен добавить в столбец атрибут parser="string". Я сделал это, но это не исправило СЕРЬЕЗНУЮ: ошибка сортировки. Я понятия не имею, что делает эту ошибку сортировки.   -  person javing    schedule 30.03.2011
comment
Вы можете преобразовать Object[] в список объектов Garbage (оставив byte[] и другие поля пустыми).   -  person Matt Handy    schedule 30.03.2011


Ответы (2)


В руководстве по Java EE я прочитал следующее:

Типы возвращаемых данных

Тип возвращаемого значения предложения SELECT определяется типами результатов содержащихся в нем выражений выбора. Если используется несколько выражений, результатом запроса является Object[], а элементы в массиве соответствуют порядку выражений в предложении SELECT, а по типу — типам результатов каждого выражения.

Теперь ваш запрос выглядит так:

SELECT g.filename, g.description,  g.uploadDate FROM Garbage g;

Из вашего класса сущностей Garbage я прочитал, что filename, description, uploadDate являются строками. Затем ваш запрос возвращает список Object[], и каждый элемент массива содержит строку, а не объект Garbage.

Если ваш массив содержит строки, а не мусор, вы не можете вызывать garbage[0].filename в своем фейслете.

Попробуйте изменить свой запрос следующим образом:

SELECT g FROM Garbage g;

Тогда вы получите List<Garbage>. В SearchEJB измените сигнатуру метода на следующую:

public List<Garbage> findAllGarbage()

Соответственно измените методы в управляемом компоненте ResultsController (теперь вам всегда нужен List<Garbage>, а не List<Garbage[]>).

Наконец, измените свой p:dataTable (показан для первого столбца):

<p:column sortBy="#{garbage.filename}">  
  <f:facet name="header">  
    <h:outputText value="Filename" />  
  </f:facet>  
  <h:outputText value="#{garbage.filename}" />
</p:column> 

ОБНОВЛЕНИЕ:

Если вы хотите сохранить свой запрос, вы можете преобразовать Object[] в список объектов Garbage и оставить отсутствующие поля пустыми. Что-то вроде этого (добавьте конструктор в свой класс Garbage):

List<Garbage> gList = new ArrayList();

for (Object[] o: query.getResultList()) {
  gList.add(new Garbage(o[0], o[1], o[2]);
}

ОБНОВЛЕНИЕ 2:

В вашем обновлении вы снова пропустили, что ваш массив содержит строки. И строки упорядочены в соответствии с вашим выражением выбора: элемент 0: имя файла, элемент 1: описание, элемент 2: uploadDate.

Измените цикл следующим образом:

for (Object o: query.getResultList()) {         
      Garbage tmpG = new Garbage();
      tmpG.setFilename(o[0]);          
      tmpG.setDescription(o[1]);
      tmpG.setUploadDate(o[2]);

      gList.add(tmpG);
    }
person Matt Handy    schedule 29.03.2011
comment
Это правильно, но я не могу просто так. Мне нужно использовать индексы, потому что это единственный способ избежать возврата byte[], который содержат объекты мусора. Если я просто перейду на SELECT g FROM Garbage g; Производительность резко упадет, потому что в каждом запросе будет фактически извлекаться файлы для поля типа byte[]. Должен быть другой путь :( - person javing; 30.03.2011
comment
Затем вам нужно использовать Object[], но я не знаю, поддерживает ли его сортировка Primefaces. А <p:column sortBy="#{garbage[0]}"> не получится? - person Matt Handy; 30.03.2011
comment
Нет не работает. В настоящее время столбец выглядит так: ‹p:column sortBy=#{garbage[0]} parser=string›... Есть небольшой прогресс, теперь консоль не говорит SEVER: Error in sorting. Но все еще не сортирует столбец. Может быть, мне просто нужно сейчас сделать какой-то кастинг в #{garbage[0]}. Но как? - person javing; 30.03.2011
comment
Я уверен, что если я изменю запрос и сделаю так, как вы говорите в своем ответе, он сработает. Есть ли способ немного настроить этот запрос и не извлекать файл атрибутов? Если бы это было возможно, проблема была бы решена. - person javing; 30.03.2011
comment
Да, я понял. Я пытаюсь это сделать, но у меня есть небольшие проблемы с циклом. Не могли бы вы помочь с кодом в моем последнем обновлении? Пожалуйста. Как видите, метод getResultsList() возвращает List‹Object›, поэтому мне нужно отфильтровать каждый Object[], представляющий каждую строку. - person javing; 30.03.2011
comment
Я только что отредактировал обновление раньше. Я заставил метод возвращать Garbage, а не Garbage[]. Но я получаю ClassCastException, когда пытаюсь выполнить tmpG.setFilename(((Garbage) o).getFilename()); Как я могу это исправить? Я также показываю изменения, которые я сделал в управляемом компоненте и в JSF в обновлении. - person javing; 30.03.2011
comment
Да, это верно. Я починил петлю. теперь есть ClassCastException и таблица отображается правильно. Но все равно не сортирует. Когда я впервые захожу на страницу, я вижу сообщение: СЕРЬЕЗНО: строка 1:61 нет жизнеспособной альтернативы символу ';' - person javing; 30.03.2011

Я знаю, что это было задано 3 года назад, но я дам вам свое решение на всякий случай, если кто-то наткнется на это.

В основном, что нужно сделать, это вызвать метод findAll() для ваших данных внутри конструктора. Но поскольку фасад EJB вводится после построения, вы не можете вызвать метод findAllGarbage() внутри конструктора. Вы можете сделать это в методе, аннотированном @PostConstruct:

@PostConstruct
public void myInitMethod(){
   garbage = searchEJB.findAllGarbage();
}

Кроме того: вызов метода findAllGarbage() в геттере сбрасывает данные, и функция сортировки не будет иметь никакого эффекта. Поэтому, возможно, удалите этот метод из геттера и переместите логику findAll в другое место, например, в действие кнопки в случае добавления данных в таблицу.

Подробнее о внедрении EJB здесь: ejbFacade is null

person Denis K    schedule 03.06.2014