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.
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.
@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:
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?
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.
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?