Dúvida Paginação JSF e JPA

Olá, pessoal, preciso criar uma paginação com JPA e JSF, estou com dúvidas. Aparentemente consegui fazer no DAO, porém tenho dúvidas de como obter isso na visão.
Abaixo o meu código no DAO e no ManagedBean respectivo:

Como fazer para "passar os parâmetros, do First e Max Results, assim, como próxima e anterior, é minha dúvida.
Obrigado.

DAO:
[code]@SuppressWarnings(“unchecked”)
public List<Empresa> buscarPorNome(String nome, int first, int max) {
Criteria query = this.session.createCriteria(Empresa.class)
.add(Restrictions.ilike(“nome”, nome, MatchMode.ANYWHERE))
.addOrder(Order.asc(“prioridade”));
query.setFirstResult(first);
query.setMaxResults(max);
return query.list();

}[/code]

ManagedBean:

	public List&lt;Empresa&gt; buscarPorNome(ActionEvent event) {
		if (this.listaPesquisa == null) {
			EmpresaRN empresaRN = new EmpresaRN();
			listaPesquisa = empresaRN.buscaPorNome(empresa.getNome());
		}
		return this.listaPesquisa;
	}

Talvez a melhor forma de fazer esta paginação não seja por este meio.

Não é mais fácil você buscar todas, sem limitar o resultado, e apresentar em um grid com paginação no grid. ?!

Você diz fazer um dataTable?(Primefaces ou RichFaces)
porque, se é essa a sugestão, pensava em tratar com recursos do próprio JSF, já que queria fazer o visual “no braço”, não ia usar esses recursos.
mas, beleza, qual é a sua sugestão?

Pensei em determinar um valor fixo para a lista para que pagine à partir de um número máximo de registros, na lógica, mais ou menso assim:
exibiria o primeiro registro ao clicar em “primeira”, ao clicar em “próxima” obteria a posição da lista e à partir dela passaria os outros resultados, com base no tamanho máximo da lista novamente. e ao clicar em anterior subtrairia certo valor para decrescer a posição da lista.

Essa era a dúvida na prática.

Ah entendi … Você deseja utilizar JSF, porém sem a suite de componentes.

A minha ideia era você utilizar a paginação de uma destas suitecases, mas se foco é outro.
Vou dar uma olhada aqui e ja te falo, no projeto que estou estamos fazendo paginação e tudo mais na mão …

[quote=smnj]Pensei em determinar um valor fixo para a lista para que pagine à partir de um número máximo de registros, na lógica, mais ou menso assim:
exibiria o primeiro registro ao clicar em “primeira”, ao clicar em “próxima” obteria a posição da lista e à partir dela passaria os outros resultados, com base no tamanho máximo da lista novamente. e ao clicar em anterior subtrairia certo valor para decrescer a posição da lista.

Essa era a dúvida na prática.[/quote]

Mas se for fazer desta forma que disse, não irá no banco a cada paginada, correto!?
Você já terá todos os registros e mãos e, ao navegar, irá apresentar um grupo de registro por vez …

Me entende ?!

Muito obrigado, Guilherme.

Realmente, Guilherme, é fato que talvez ganharia performance com isso, porém, preciso personalizar a exibição de um modo muito específico, por isso, realmente precisaria fazê-la “no braço”.

Conversei com o pessoal aqui e vi a nossa solução.
É um pouco complicado de explicar, vou entender melhor com o cara que criou e te mando a solução assim que puder.

Obrigado, Guilherme.
Caso precise meu e-mail é smnjr@hotmail.com

compartilhe conosco a solução…

Qual a vantagem de buscar tudo do banco e fazer apaginacao so na view?
O consumo de recursos será o mesmo, e se tiver 1kk de tuplas, e ai?

O que indica?
Realmente concordo que consumirá muito recurso…
Só estava pensando em personalizar a dataTable, o que recomenda?

Pensei em paginar do banco…
limitando a quantia de registros de dez em dez, passando um MaxResult(quantia máxima de resultados) e algum tipo de offset, que armazerne a posição da lista, mas não sei como fazer na prática.

poxa primefaces ia ser perfeito pra isso…

http://www.primefaces.org/showcase/ui/datatablePagination.jsf

sem ofenças mas… pq reinventar a roda???

não rola de armazenar esses valores no MB?
ai de acordo com o valor q o usuario solicitar ele vai no DB e busca???

Você pode utilizar o primefaces e paginar de modo lazy: Lazy JSF Datatable Pagination (Primefaces).

Desse modo você não precisa buscar ziguilhões de resultados para exibir na tela. Busca apenas o que é necessário para ser exibido.

Caso você não queira utilizar Primefaces mas criar sua própria pesquisa, você pode olhar nesse exemplo de como realizar uma consulta no DB paginada.

Muito obrigado, JakeFrog, olharei o seu post, mais uma vez, quebrando meu galho, valw, é bom contar com você.
Quanto ao colega, anterior, te agradeço realmente, apesar de gostar do primefaces e do richfaces, eles limitam bastante em alguns instantes o design.

Vamos a solução: (pode não ser a melhor, mas acho que atende o seu problema).

Esta classe em anexo tem a inteligencia total da paginacao, a parte mais dificil esta feita.

Objetivo: Você deve apresentar toda as possiveis paginas em tela (atributo numberOfPages do objeto Paginacao) e quando ele clicar em algums dos numeros, você coloque este numero dentro do atributo PAGE do objeto Paginacao.

é simples fazer isto: Você declara esta classe Paginacao como um atributo do seu managedBean e na tela mapeia que algum componente: #{mb.paginacao.page} quando foi feito o submit ou ajax, este valor já estará dentro deste objeto e neste mesmo submit você chamará o método pesquisar o qual irá passar ao service este objeto Paginação que já terá calculado o minResult e maxResult.

Dentro deste service você irá precisar descobrir uma coisa: a quantidade de registros que sua consulta vai retornar! você da um COUNT, passando seus parametros, na tabela e SETA o resultado dentro do objeto paginação, na propriedade totalOfRows.

Dai você faz uma busca dos registro, passando seus parametros. Dai você utiliza aquele DAO que você criou que recebe minResult e maxResult, passando as propriedades getFirstResult e getMaxResult do objeto Paginacao, respectivamente.

Retorna a lista de registros e apresenta em tela.

Existe um atributo do objeto Paginacao, numberOfPages, que terá todas as possiveis páginas (link todos estes numeros para que ao submitar a página ele ENVIE o valor do número da página para o atributo PAGE, o que mencionei acima) . Apresente-o na tela juntamente com seu grupo de registros, quando o usário clicar em um destes números o objeto paginação terá a pagina desejada e irá ter o maxResult e firstResult prontos para seu DAO trazer a quantidade de registros corretamente.

Segue a classe que tem a inteligencia de paginar, ela deve ser trafegada até o DAO para receber o valor do count, como também passar o valor do minResult e maxResult


import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

public class Paginacao implements Serializable {
    
    private static final long serialVersionUID = -1L;


    /**
     * Página corrente
     */
    private int page = 1;
    
    /**
     * Divisor de página.
     */
    private Float pageDivisor = (float) 10;
    
    /**
     * Total de registros
     */
    private Float totalOfRows = 0F;
    
    /**
     * List quantidade de páginas
     */
    private List<Integer> numberOfPages = new LinkedList<Integer>();
    
    /**
     * Retorna o primeiro indice da paginacao
     */
    public int getFirstResult(){
        int firstResult = (int) ((page-1) * pageDivisor);
        
        return firstResult >= 0 ? firstResult : 0;
    }
    
    /**
     * Retorna último indice de paginacao 
     */
    public int getMaxResult(){
        return pageDivisor.intValue();
    }

    public void setTotalOfRows(float totalOfRows) {
        this.totalOfRows = totalOfRows;
        
        numberOfPages = new LinkedList<Integer>();
        int qtd = ((Double) Math.ceil(this.totalOfRows / pageDivisor)).intValue();
        
        for(int i=1; i<= qtd; i++){
            numberOfPages.add(i);
        }            
    }
    
    public void setPageDivisor(int pageDivisor) {
        this.pageDivisor = new Float(pageDivisor);
    }
    
    public int getPageDivisor() {
        return pageDivisor.intValue();
    }
    
    public List<Integer> getDivisors(){
        List<Integer> lst = new LinkedList<Integer>();
        lst.add(5);
        lst.add(10);
        lst.add(25);
        lst.add(50);
        lst.add(100);
        
        return lst;        
    }
    

    public int getTotalOfPages() {
        return numberOfPages.size();
    }

    
    public int getTotalOfRows() {
        return totalOfRows.intValue();
    }
    
    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public List<Integer> getNumberOfPages() {
        return numberOfPages;
    }   
}

Acho que isto já lhe dará um LUZ para este problema.

Obrigado, vou trabalhar nesta idéia.