[ RESOLVIDO ] - Loop repetindo objeto

12 respostas
J

Existe alguma possibilidade de um “for” fica repetindo o mesmo objeto em um loop?

Ex:

for(String temp: list){
 System.out.println( temp );
}

Gostaria de saber se isso já aconteceu com alguém? Porque tive um problema deste e gostaria de identificar o que aconteceu se o problema foi do banco que retornou linhas iguais ou se foi do java?

12 Respostas

D

Dessa maneira duvido muito que exista um jeito de repetir o mesmo item do for. O “for tradicional” até teria como, mas se você fez assim sua lista contém elementos repetidos, muito provavelmente.

Depure o programa e veja o conteúdo que tem na lista, aí você tira suas dúvidas.

V

Também nunca vi isso.

Aliás, nunca vi uma linguagem não fazer o que a documentação diz que faz (exceto em linguagens da MS).

J

A minha query não me retorna linhas repitidas, só aparece registros repetidos quando eu faço o loop no list que veio do banco.
Eu estou usando spring com jpa.
O meu código é simples.

public Set<RecentCustomer> getRecentSignedUpCustomers() {
        String query = "select * from data.list_on_demand_channel_customers();";

        Set<RecentCustomer> customerList = new HashSet<RecentCustomer>();
        ArrayList<RecentCustomer> temp = null;
        long startTime = System.currentTimeMillis();
        try {
                temp = (ArrayList<RecentCustomer>) this.getEntityManager().createNativeQuery( query, RecentCustomer.class ).getResultList();
        	customerList.addAll(temp);
        } catch(Exception e) {
            LOGGER.warn( this.getToken(), new Throwable( e ) );
        }

            int total = temp.size();
            LOGGER.trace( "Total recent customers in ArrayList temp:" + total );
            for(int i = 0; i < total; i++) {
                LOGGER.trace( "Recent Customer: " + temp.get( i ).getMsisdn() + " - " + 
                        temp.get( i ).getIdCustomer() + " - "
                        + temp.get( i ).getIdChannel() );
            }
        temp.clear();
        temp = null;
        return customerList;
    }

Eu realmente não vejo nada de errado com o código acima para está repetindo registro, achei que fosse o banco, mas quando executo a query ela me retorna linhas diferentes.

V

Como está implementado o método hashCode() da classe Costumer?

J

Está sendo implementado desta maneira:

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((idChannel == null) ? 0 : idChannel.hashCode()); result = prime * result + ((idCustomer == null) ? 0 : idCustomer.hashCode()); result = prime * result + ((msisdn== null) ? 0 : msisdn.hashCode()); return result; }

Sendo que o idChannel pode se repetir o idCustomer e o msisdn não, só se repete o idCustomer e o msisdn se o idChannel for diferente, por exemplo:

OBJA: idChannel = 1, idCustomer = 1, msisdn = 777;
OBJB: idChannel = 1, idCustomer = 2, msisdn = 888;
OBJC: idChannel = 3, idCustomer = 2, msisdn = 888;
F

Verifique se o hibernate / JPA está retornando um resultado multrow (duplicação de linhas no JOIN).

flws

J
fantomas nesta classe não tem joins apessar de ter ids... Achei aonde está o erro pela sua sugestão. O erro estava na configuração do bean, ou seja, nas annotations. Abaixo segue como estava:
public class RecentCustomer implements Serializable{
	
	private static final long serialVersionUID = 1L;

        @Id
	@Column(name="id_channel")
	private Long idChannel;
	private String cfs;
	private String price;
	private String sender;
	private String msisdn;
        @Column(name="id_customer")
	private Long idCustomer;
	private int status;
        private String resource;
}
Como tinha falado anteriormente, o idChannel se repete várias vezes e o @Id estava neste campo, quando mudei a annotation de lugar parou de repetir as linhas, mas ai acabo caido em outro problema, o idCustomer também se repete em menor quantidade que o idChannel, como resolver isso? Gostaria, se possível, se alguém com mais experiência explicasse o que aconteceu, por que as linhas repetiram quando a annotation fica no idChannel?
F

Opa!

Então…

Olhando um pouco mais o teu código notei que vc utiliza uma lista do tipo Set para retornar o resultado da consulta. Acontece que este tipo de lista não deveria permitir elementos repetidos; para isto, no seu caso, o mecanismo da lista deveria utilizar o método equals da sua entidade para atingir este objetivo.

Como vc diz que a lista possui elementos repetidos estou suspeitando que o métodos equals na sua classe deve estar com problemas; lembrando que o ideal é que sempre que vc sobreescrever o método hash sobreescreva tambem o método equals.

Tente verificar o conteúdo da tabela correspondente para se certificar que realmente as linhas se repetem. O critério para perceber se uma linha está realmente repetida é verificar sua chave primária (acho que vc sabe disso mas…), estou começando a pensar que a sua tabela possui uma chave primária composta se isto for verdade vc terá que montar uma classe correspondente a sua chave e utilizar a anotação @Embedded na sua entidade.

flws

J

Eu coloquei o set para o java tirar as linhas repetidas, só para ver se o problema era no java. E acabou dando certo porque o número de registro retornado era diferente da query.

E a minha tabela usa pk composta sim. Vou ter que fazer uma classe para essa PK. Eu só tenho dúvida nesta parte como ficaria o mapeamento desta classe com a entidade?

F

Dá uma olhada no conteúdo deste link para vc ter uma idéia.

http://www.java2s.com/Tutorial/Java/0355__JPA/EmbeddedCompoundPrimaryKey.htm

Vale a pena explorar mais esta tema em livros / tutoriais

flws

J

Valeu pela ajuda, está tudo funcionando agora.
Obrigado a todos!

M

ViniGodoy:
Também nunca vi isso.

Aliás, nunca vi uma linguagem não fazer o que a documentação diz que faz (exceto em linguagens da MS).


:lol: Bem observado… :slight_smile:

Criado 4 de janeiro de 2010
Ultima resposta 5 de jan. de 2010
Respostas 12
Participantes 5