[ RESOLVIDO ] - Loop repetindo objeto

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?

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.

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).

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.

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

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;

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

flws

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:

[code]
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;

}[/code]
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?

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

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?

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

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

[quote=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).[/quote]
:lol: Bem observado… :slight_smile: