2

I have a problem with the primefaces dataTable component. I dont know why it does not short the data in the table when i click on it.

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

This is the managed bean

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

}

This is the EJB that allows data access

@Stateless(name = "ejbs/SearchEJB")

public class SearchEJB implements ISearchEJB {

@PersistenceContext
private EntityManager em;


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

}

And this is the entity(Data representation)

@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

As shown in the image there is no changes when the sort buttons are clicked: enter image description here

This is what the console says:

SEVERE: Error in sorting

UPDATE

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

The modified managed bean

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

}

The modified 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> 
javing
  • 12,307
  • 35
  • 138
  • 211
  • I don't get what you are trying to do. You have a list of arrays and your table would print a String representation of a Garbage instance into every cell. A bit more info about your data structure would help (maybe). – Matt Handy Mar 29 '11 at 17:12
  • I just updated and added how the EJB looks like, and also the Entity Garbage. I hope that can help you understand. Do i need to add any script tag on my head tag maybe? I dont understand why it is not working. – javing Mar 29 '11 at 19:03
  • I found something interesting at this guide in page 94 web-cinema.googlecode.com/files/primefaces_users_guide_140210.pdf It is the primefaces guide. It says that if my datatable is dynamic i should add parser=”string” attribute to the column. I did it but it didnt fix the SEVERE: Error in Sorting thing. I have no clue what is making that sorting error. – javing Mar 29 '11 at 20:49
  • You could transform the Object[] into a List of Garbage objects (leaving the byte[] and the other fields empty). – Matt Handy Mar 29 '11 at 21:34

2 Answers2

0

I'm aware this was asked 3 years ago but I'll give you my solution just in case someone stumbles upon this.

Basically what needs to be done is to call the findAll() method for your data inside a constructor. But since EJB facade is injected post construction, you can't call the findAllGarbage() method inside a constructor. You can do it in a method annotated with @PostConstruct:

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

Also: calling the findAllGarbage() method in a getter resets the data and the sort function won't have any effect. So maybe remove that method from the getter and move the findAll logic elsewhere, for example on a button action in case of adding data to the table.

More about EJB injection here: ejbFacade is null

Community
  • 1
  • 1
Denis K
  • 150
  • 1
  • 9
0

From the Java EE tutorial I read the following:

Return Types

The return type of the SELECT clause is defined by the result types of the select expressions contained within it. If multiple expressions are used, the result of the query is an Object[], and the elements in the array correspond to the order of the expressions in the SELECT clause, and in type to the result types of each expression.

Now your query looks like:

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

From your entity class Garbage I read that filename, description, uploadDate are Strings. Then your query returns a list of Object[] and each array element contains a String and not a Garbage object.

If your array contains Strings and not Garbage, you cannot call garbage[0].filename in your facelet.

Try to change your Query in the following way:

SELECT g FROM Garbage g;

Then you get a List<Garbage>. In the SearchEJB change the method signature to the following:

public List<Garbage> findAllGarbage()

Change the methods in your ResultsController managed bean accordingly (now you always need a List<Garbage> and not a List<Garbage[]>).

Finally modify your p:dataTable (shown for the first column):

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

UPDATE:

If you want to keep your query you could convert the Object[] into a list of Garbage objects and leave the missing fields empty. Something like this (add a constructor to your Garbage class):

List<Garbage> gList = new ArrayList();

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

UPDATE 2:

In your update you missed again, that your array contains strings. And the strings are ordered as your select expression is ordered: element 0: filename, element 1: description, element 2: uploadDate.

Change your loop in the following way:

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

      gList.add(tmpG);
    }
Community
  • 1
  • 1
Matt Handy
  • 29,855
  • 2
  • 89
  • 112
  • That is right but i cant just do that. I need to use the indexes, because is the only way i can avoid returning the byte[] that the garbage objects contain. If i change to just SELECT g FROM Garbage g; The performace will drop drastically because in each query it will be actually retrieving files for the byte[] type field. There has to be another way :( – javing Mar 29 '11 at 21:00
  • Then you have to use the Object[] but I don't know if Primefaces sorting supports it. And `` won't work? – Matt Handy Mar 29 '11 at 21:05
  • No doesnt work. Currently the column looks like this: ... There is a bit of progress, now the console does not say SEVERE: Error in sorting. But still does not sort the column. Maybe i just need now to do some kind of casting at "#{garbage[0]}". But how? – javing Mar 29 '11 at 21:16
  • I am sure if i change the query and do the way you say in your answer it will work. Is there any way to just tune that query a little and dont retrieve the attribute file? If that could be possible the problem would be solved. – javing Mar 29 '11 at 21:33
  • Yeah i understand. I am trying to do that but i have a bit of trouble with the loop. Could you give a hand with the code in my last update? Please. As you see the method getResultsList() returns List, so i have to filter out each Object[] that represents each row. – javing Mar 29 '11 at 22:25
  • I just edited the update before. I made the method return Garbage and not Garbage[].But i get ClassCastException when i try to do tmpG.setFilename(((Garbage) o).getFilename()); How could i fix that? I also show in the changes i made in the managed bean and in the JSF in the Update. – javing Mar 29 '11 at 22:44
  • Yeah thats right. I did fix the loop. now there is ClassCastException and the table displays correctly. But it still does not sort. When i first time navigate to the page i see the message: SEVERE: line 1:61 no viable alternative at character ';' – javing Mar 30 '11 at 08:42