JSF retornando lista triplicado

12 respostas
jsfjava
E

Boa noite pessoal, estou montando um site em JSF e tive um problema no retorno de um link que lista produtos de uma determinada categoria. Ao clicar ele mostra o tamanho da lista corretamente (ex.: foram encontrados 3 produtos), mas o retorno fica triplicado (se haviam 3 objetos ele mostra 9, repetindo os mesmos elementos 3 vezes)… Agora empaquei nesta parte, já que não consigo descobrir se é um problema devido ao escopo de Sessão que escolhi, algum bug do JSF, apenas erro de lógica ou qualquer outra coisa…

trecho de códio responsável pelo retorno:

Sua busca retornou resultado(s):

ManagedBean que faz a ligação:

@SuppressWarnings(deprecation)

@ManagedBean(name = pesquisaManagedBean)

@ViewScoped

public class PesquisaManagedBean {

private Pesquisa pesquisa;

private Produto produto;

private HtmlDataTable dataTable;

private ProdutoDAO produtoDAO;

private List produtos;

private String categoria;

//private List produtosPesquisa;

private List wstComments = new ArrayList();

private List bstComments = new ArrayList();

private BigDecimal mediaPrecos;

private List precos;

//private Integer size = 0;
public PesquisaManagedBean(){
	this.pesquisa = new Pesquisa();
	this.produto = new Produto();
	this.produtoDAO = new ProdutoDAO();
	this.produtos = new ArrayList<Produto>();
	this.mediaPrecos = new BigDecimal("0.0");
	this.precos = new ArrayList<BigDecimal>();
	//this.produtosPesquisa = new ArrayList<Produto>();
}

//retorna produtos
//String categoria
public List<Produto> getProdutosCategoria(){
	categoria = this.getIdentificador();
	try{
		for(Produto p : produtoDAO.listarProdutoCategoria(categoria)){
			produtos.add(p);
		}
	}catch(Exception ex){
		throw new RuntimeException(ex);
	}
		
	return produtos;
}

public List<Produto> getProdutosId(){
	categoria = this.getIdentificador();
	
	try{
		produtos.addAll(produtoDAO.listarProdutoId(Integer.valueOf(categoria)));
		return produtos;
	}catch(Exception ex){
			throw new RuntimeException(ex);
	}
	
}

public HtmlDataTable getDataTable() {
	return dataTable;
}

public void setDataTable(HtmlDataTable dataTable) {
	this.dataTable = dataTable;
}

public String getIdentificador(){
	HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();    
	String id = request.getParameter("q");
	
	return id;
}

public String getQuery(){
	HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();    
	String id = request.getParameter("r");
	
	return id;
}

/** recebe idCategoria, passa para o DAO que alimenta a lista produtos, 
 * o size() desta lista alimenta a quantidade de retornos para a busca **/
public int getSizeProduto(){
	int s = 0;
	try{
		categoria = this.getIdentificador();
		produtos.addAll(produtoDAO.listarProdutoCategoria(categoria));
		s = produtos.size();
	}catch(SQLException ex){
		throw new RuntimeException(ex);
	}
	
	return s;
}

public String getNome() {
	int cd = 1;
	Produto p = new Produto();
	p.setNmProduto(produtoDAO.getNomeProduto(cd));
	
	String nome = p.getNmProduto();
	
	return nome;
}

/*** Retorna os dois comentários melhor pontuados de produto com nome semelhante e mesmo modelo ***/
public List<String> getWstComments(){
	//acessa o primeiro item da lista produtos (o atual, só tem um neste acesso),
	//deste objeto retiram-se os nomes do modelo e produto para parâmetro do select
	String produto = produtos.get(0).getNmProduto();
	String modelo = produtos.get(0).getModelo();
	
	int cont = 1;
	produtoDAO = new ProdutoDAO();
	List<String> p = produtoDAO.getWstComments(produto, modelo);
	for(String prod : p){
		this.wstComments.add(prod);
		cont ++;
		if(cont>=2 || cont == p.size()){
			break;
		}
	}
	
	return this.wstComments;
}

/*** Retorna os dois comentários menor pontuados de produto com nome semelhante e mesmo modelo ***/
public List<String> getBstComments(){
	//acessa o primeiro item da lista produtos (o atual, só tem um neste acesso),
	//deste objeto retiram-se os nomes do modelo e produto para parâmetro do select
	String produto = produtos.get(0).getNmProduto();
	String modelo = produtos.get(0).getModelo();
	int categoria = produtos.get(0).getIdCategoria();
;

int cont = 1;

produtoDAO = new ProdutoDAO();
List<String> p = produtoDAO.getBstComments(produto, modelo);

	for(String prod : p){
		this.bstComments.add(prod);
		cont ++;
		if(cont>=2 || cont == p.size()){
			break;
		}
	}
	
	return this.bstComments;
}

public BigDecimal getMediaPrecos(){
	try{
		this.precos.addAll(produtoDAO.getPrecos("Celular Windows", "W-480"));
		
		for(BigDecimal preco: this.precos){
			//mediaPrecos.add(valor) nao funciona, é preciso usar atribuição
			mediaPrecos = mediaPrecos.add(preco);
		}
		
		mediaPrecos = mediaPrecos.divide(new BigDecimal(String.valueOf(this.precos.size())), 2, RoundingMode.HALF_EVEN);
	}catch(Exception ex){
		System.out.println(ex.getMessage());
	}
	
	return mediaPrecos;
}


public List<Produto> getPesquisaString() throws SQLException {
	String query = this.getIdentificador();
	try{
		for(Produto p : produtoDAO.listaProdutoQuery(this.validaQuery(query))){
			produtos.add(p);
		}
	}catch(SQLException ex){
		throw new RuntimeException(ex);
	}
 	
	return produtos;
}
 

public String validaQuery(String query){
	String[] nulos = {"á","é","í","ó","ú","´","ä","ë","ï","ö","ü","¨",
			"ã","õ","~","à","è","ì","ò","ù","`","^","â","ê","î","ô","û"};
	for(String n:nulos){
		query = query.toLowerCase().replaceAll(Pattern.quote(n), "_");
	}
	return query;
}

public List<Produto> getBstProdutos() throws SQLException{
	int idCategoria = 1;
	
	int i = 0;
	try{
		for(Produto p: produtoDAO.listarProdutoCategoria(idCategoria)){
			produtos.add(p);
			while(i<5){
				i++;
				if(i==4 || i == produtoDAO.listarProdutoCategoria(idCategoria).size())
				   break;
			}
		}
	}catch(SQLException ex){
		System.out.println(ex.getMessage());
	}
	
	return produtos;
}

public List<Produto> getWstProdutos() throws SQLException {
	int idCategoria = 1;
	
	try{
		List<Produto> p = produtoDAO.listarProdutoCategoria(idCategoria);
		int i = p.size();
		int cont = 5;
		
		while(cont != 0){
			produtos.add(p.get(i--));
			if(cont == i){
				break;
			}
			cont--;
		}
		
		
	}catch(SQLException ex){
		System.out.println(ex.getMessage());
	}
	
	return produtos;
}

public Pesquisa getPesquisa() {
	return pesquisa;
}

/** recebe dado setado para a query de pesquisa e retorna o path da página para onde será enviado **/
public String getSearch(){
	String query = pesquisa.getQuery();
	
	return "/pesquisa?q="+query;
}

}

método do DAO:

public List listarProdutoCategoria(String nmCategoria) throws SQLException {

String sql = SELECT p.idProduto, p.nmProduto, p.dsDescricao, p.dtCadastro, p.idCategoria, 

+ c.nmCategoria, p.nmModelo, p.cdPreco, p.pontuacao+

 FROM Produto p inner join Categoria c ON c.nmCategoria = ? and p.idCategoria = c.idCategoria;
PreparedStatement stmt = conn.prepareStatement(sql);
	
	Produto p;
	try{
		stmt.setString(1, nmCategoria);
		ResultSet rs = stmt.executeQuery();
		
		while(rs.next()){
			p = new Produto();
			p.setIdProduto(rs.getInt("idProduto"));
			p.setNmProduto(rs.getString("nmProduto"));
			p.setComent(rs.getString("dsDescricao"));
			p.setDtCadastro(rs.getDate("dtCadastro"));
			p.setIdCategoria(rs.getInt("idCategoria"));
			p.setModelo(rs.getString("nmModelo"));
			p.setPreco(rs.getBigDecimal("cdPreco"));
			p.setPontuacao(rs.getInt("pontuacao"));
			produtoCategoria.add(p);
		}
		rs.close();
		stmt.close();
	}catch(SQLException ex){
		System.out.println(ex.getMessage());
	}
	
	return produtoCategoria;
}

12 Respostas

Rodrigo_Void

Pq não está criando a lista produtoCategoria dentro do método listarProdutoCategoria?

Rodrigo_Void

Procure observar mais oq ocorre cm o código q vc fez. No trecho acima vc está comparando i com o size da busca, mas vc faz novamente toda busca E EM LOOP só pra usar o size, otimização ZERO. Salva os resultados uma vez em uma var e reutiliza.

Diego_Emmanuell
<blockquote><div class="quote-author">"Edu_Reis:</div>
public List&lt;Produto&gt; getProdutosCategoria(){
	categoria = this.getIdentificador();
	try{
		for(Produto p : produtoDAO.listarProdutoCategoria(categoria)){
			produtos.add(p);
		}
	}catch(Exception ex){
		throw new RuntimeException(ex);
	}

	return produtos;
}
</blockquote>

Pq não muda para:

public List<Produto> getProdutosCategoria(){
	categoria = this.getIdentificador();
	try{
		produtos.addAll(produtoDAO.listarProdutoCategoria(categoria));
	}catch(Exception ex){
		throw new RuntimeException(ex);
	}
		
	return produtos;
}
Diego_Emmanuell

Eu sendo você veria o seu código novamente, porque você está usando vários loops onde toda vez faz uma conexão ao banco… tipo
for(Produto p : produtoDAO.listarProdutoCategoria(categoria)){ produtos.add(p); }

Diego_Emmanuell

Acredito inclusive que um dos erros possa estar aii…

Ex. for(Produto p : produtoDAO.listarProdutoCategoria(categoria)){ produtos.add(p); }

Nesse exemplo ai, na segunda repetição ele vai no banco e trás a lista completa de novo.

Rodrigo_Void

Corrigindo, só chamará uma vez o método listarProdutoCategoria no foreach. É diferente doq na situação onde o cara tá chamando o método de busca DENTRO DO BLOCO do foreach.

Diego_Emmanuell

Tem razão. confundi com um for(int i = 0; i < produtoDAO.listarProdutoCategoria(categoria); i++)

E

Sou iniciante e esse é o primeiro código imenso (digamos que não tive muito bom senso na hora de escolher o TCC haha) que estou criando… ^^ Esse é um MB de outros 4 :confused:

Parecia ser o mais certo :confused: :confused:

E

Opa! Vou dar uma revisada aqui =D

Diego_Emmanuell

Devagar você vai vendo o que é melhor. Siga firme e forte.

E

Estou praticando bastante para chegar nisso hehe Valeu mesmo Diego!!

E

Achei o problema!!

Ao fazer o retorno da quantidade de dados retornados na pesquisa (Ex.: Sua pesquisa retornou x produtos), eu estava iniciando a lista novamente :confused: … Falha minha… E usei essa lista mas de uma vez … :confused: :confused:

Quanto as outras pontuaçãoes:

Quando tento usar o .addAll ele não consegue adicionar os dados na lista… pq? Não descobri ainda… e quando tento deixar o ProdutoDAO sem iniciar dentro daquelas funções, ele dá erro :s

Minha solução por ora está sendo a mais simples para mim, tirar o aviso de quantidade de retornos para não triplicar a lista ^^’ Tentei várias outras formas de pegar o tamanho da lista, direto o ponto size na lista, usar getter para pegar a lista e seu tamanho, não funcionou ^^’ Se eu descobrir algo mais, edito aqui…

Criado 28 de novembro de 2018
Ultima resposta 1 de dez. de 2018
Respostas 12
Participantes 3