2
votes

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> 
2
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
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
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
You could transform the Object[] into a List of Garbage objects (leaving the byte[] and the other fields empty).Matt Handy

2 Answers

0
votes

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);
    }
0
votes

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