-1

I need some help to implement lazy loading in my app.

dataTable:

<p:dataTable var="log" value="#{logger.getAll()}"
        widgetVar="loggerTable"
        emptyMessage="No logs found with given criteria"
        rowStyleClass="#{log.status eq 'uspesno' ? 'old' : null}">
        <!-- //Main 
        <f:facet name="header">
            <p:outputPanel>
                <h:outputText value="Search all fields:" />
                <p:inputText id="globalFilter" onkeyup="PF('loggerTable').filter()"
                    style="width:150px" placeholder="Enter keyword" />
            </p:outputPanel>
        </f:facet>  -->

        <p:column filterBy="#{log.mdmId}" headerText="Id"
            footerText="contains" filterMatchMode="contains">
            <h:outputText style="display: block; width:100%; "
                value="#{log.mdmId}" />
        </p:column>
        <p:column filterBy="#{log.pib}" headerText="pib"
            footerText="contains" filterMatchMode="contains">
            <h:outputText value="#{log.pib}" />
        </p:column>

        <!-- // poruka 
        <p:column filterBy="#{log.poruka}" headerText="message"
            footerText="contains" filterMatchMode="contains">
            <h:outputText value="#{log.poruka}" />
        </p:column> -->
        <p:column filterBy="#{log.status}" headerText="status"
            footerText="contains" filterMatchMode="contains">
            <h:outputText value="#{log.status}" />
        </p:column>
        <p:column filterBy="#{log.mbr}" headerText="mbr"
            footerText="contains" filterMatchMode="contains">
            <h:outputText value="#{log.mbr}" />
        </p:column>
        <p:column filterBy="#{log.datumUpisa}" headerText="datumupisa"
            footerText="contains" filterMatchMode="contains">
            <h:outputText value="#{log.datumUpisa}" />
        </p:column>
        <p:column style="width:40px;text-align: center">
            <p:commandButton update=":form:logDetail"
                oncomplete="PF('logDialog').initPosition();PF('logDialog').show()"
                icon="fa fa-search" title="View">
                <f:setPropertyActionListener value="#{log}"
                    target="#{logger.selectedLog}" />
            </p:commandButton>
        </p:column>
    </p:dataTable>

ManagedBean:

private static final long serialVersionUID = 1L;

private Integer mdmId;


private String pib;


private String mbr;


private Date datumUpisa;


private String status;


private String poruka;

private Logger selectedLog;

public Logger getSelectedLog() {
    return selectedLog;
}

public static List<Logger> getAll(){
    List<Logger> lista = LoggerDAO.getAll();
    return lista;
} // ...

DAO:

public static List<Logger> getAll() {
    Connection con = null;
    PreparedStatement ps = null;
    List<Logger> lista = new ArrayList<>();
    try {
        con = DataConnect.getConnection();
        ps = con.prepareStatement("Select * from log");

        ResultSet resultSet = ps.executeQuery();

        while (resultSet.next()) {

            int mdm_id = resultSet.getInt(1);
            String pib = resultSet.getString(2);
            String mbr = resultSet.getString(3);
            Date datumUpisa = resultSet.getDate(4);
            String status = resultSet.getString(5);
            String poruka = resultSet.getString(6);

            Logger log = new Logger();
            log.setMbr(mbr);
            log.setMdmId(mdm_id);
            log.setDatumUpisa(datumUpisa);
            log.setPib(pib);
            log.setPoruka(poruka);
            log.setStatus(status);
            lista.add(log);

        }

    } catch (SQLException ex) {
        System.out.println("Login error -->" + ex.getMessage());
        return null;
    } finally {
        DataConnect.close(con);
    }
    return lista;
}

I would like to implement lazy loading, but i do not know if it's possible. There is no example with database provided by primefaces. Do i need to write queries to get a couple of rows or i should return all rows at once. I need some help and advices, thank you

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Rattus
  • 11
  • 2
  • 1
    And read https://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times – Kukeltje Jul 17 '19 at 18:07
  • 1
    Possible duplicate of [How to query data for Primefaces dataTable using lazy loading and pagination](https://stackoverflow.com/questions/13972193/how-to-query-data-for-primefaces-datatable-using-lazy-loading-and-pagination) – Kukeltje Jul 17 '19 at 19:03

2 Answers2

1

I'm taking into account that you want to implement pagination.

First modify the <p:dataTable> to this below :

<p:dataTable lazy="true" rows="8" paginator="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="2,4,6,8"></p:dataTable>

Then add filterBy, sortBy(according to what you want) in every <p:column> field.

Then, in the Managed Bean class, create private field : private LazyDataModel<Logger> lazyDataModel;

Create appropriate getter and setter for the LazyDataModel<Logger> lazyDataModel in the managed bean.

Now in the getAll() method but make the return type to void, add this :

public static void getAll(){
    lazyDataModel = new LazyLoggerDataModel(LoggerDAO.getAll());
}

Create a LazyLoggerDataModel class which extends LazyDataModel<Logger>. It will look like this :

public class LazyLoggerDataModel extends LazyDataModel<Logger> {

    private List<Logger> loggerList;

    public LazyLoggerDataModel(List<Logger> loggerList) {
        this.loggerList = loggerList;
    }

    @Override
    public Logger getRowData(String rowKey) {
        ....
    }

    @Override
    public Object getRowKey(Logger logger) {
        return ...;
    }

    @Override
    public List<Logger> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
       ... put here the main logic..
    }
} 

Please refer to the Lazy - loading example from Primefaces Official for more :

Link Here : Primefaces Lazy Loading Example

Hope this will help you :)

Anish B.
  • 9,111
  • 3
  • 21
  • 41
  • I don't understand what is lazy here ( lazyModel = new LazyCarDataModel(service.createCars(200)); ) They loaded 200 cars at once. My dataset is huge and that's a problem. – Rattus Jul 17 '19 at 14:26
  • They are taking to show you the example. Now you have to implement it. You will not take `String[]`. You will pass your `List` that you are getting from `LoggerDAO.getAll()`. I have told in the answer only. – Anish B. Jul 17 '19 at 14:28
  • 2
    The load() method gets page size and first entity to show as arguments. Construct a query that limits results to this set. If page size ist 30, you'll load 30 of your 121407 entities only for each page switch. That's lazy @Rattus – Selaron Jul 17 '19 at 19:03
  • @Selaron I agree with you fully. – Anish B. Jul 17 '19 at 19:16
  • the 'service.createCars(200)' is to 'fake' a database, the complete full database. And what @Selaron states can be seen in the showcase as well. But really great is to use 'OptimusFaces' from OmniFaces... Use it! – Kukeltje Jul 17 '19 at 23:03
-2

This article solved my problem:

getAll() in DAO:

public static List<Logger> getAll(int from , int to) {
    Connection con = null;
    PreparedStatement ps = null;
    List<Logger> lista = new ArrayList<>();
    try {
        con = DataConnect.getConnection();
        int upper = from + to;
        ps = con.prepareStatement("Select * from log limit ?,?");
        ps.setInt(1, from);
        ps.setInt(2, upper);

        ResultSet resultSet = ps.executeQuery();

        while (resultSet.next()) {

            int mdm_id = resultSet.getInt(1);
            String pib = resultSet.getString(2);
            String mbr = resultSet.getString(3);
            Date datumUpisa = resultSet.getDate(4);
            String status = resultSet.getString(5);
            String poruka = resultSet.getString(6);

            Logger log = new Logger();
            log.setMbr(mbr);
            log.setMdmId(mdm_id);
            log.setDatumUpisa(datumUpisa);
            log.setPib(pib);
            log.setPoruka(poruka);
            log.setStatus(status);
            lista.add(log);

        }

    } catch (SQLException ex) {
        System.out.println("Login error -->" + ex.getMessage());
        return null;
    } finally {
        DataConnect.close(con);
    }
    return lista;
}
double-beep
  • 5,031
  • 17
  • 33
  • 41
Rattus
  • 11
  • 2
  • Bad solution... (not because of the blog but the way you use `getAll()` https://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times Better yo use https://github.com/omnifaces/optimusfaces – Kukeltje Jul 18 '19 at 09:06