@ManyToMany + Busca duplicada com Criteria [RESOLVIDO]

Guj’s estou fazendo uma busca simples de todos os registros em uma tabela na minha app e aconteceu uma coisa muito estranha, gostaria de saber como resolvo isso.

Tenho a Classe Parceiro.java

@Entity
public class Parceiro implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2455166146414894872L;
	
	/* codigos de habilitados e desabilitados */
	public static final int ENABLED = 1;
	public static final int DISABLED = 0;
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "parceiro")
	@SequenceGenerator(name = "parceiro", sequenceName = "parceiro_seq")
	@Column(name = "id_parceiro")
	private long id;
	
	@Column(name = "nm_parceiro", nullable = false, length = 50, unique = true)
	private String nome;
	
	@Column(name = "nm_parceiro_performance", nullable = false, length = 50)
	private String nomePerformance;
	
	@Column(name = "nu_retentativa", nullable = false)
	private int retentativa;
	
	@Column(name = "nu_timeschedule", nullable = false)
	private int timeSchedule;
	
	@Column(name = "cd_ativo", nullable = false)
	private int ativo;
	
	@Column(name = "dt_criacao", nullable = false)
	private Date dtCriacao;
	
	@Column(name = "dt_alteracao", nullable = false)
	private Date dtAlteracao;
	
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "parceiro_la",
		joinColumns=@JoinColumn(name = "id_parceiro"),
		inverseJoinColumns=@JoinColumn(name = "id_la"))
	private List<LA> las;

LA.java

@Entity
public class LA implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2492355244196697003L;
	
	/* codigos de habilitados e desabilitados */
	public static final int ENABLED = 1;
	public static final int DISABLED = 0;
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "la")
	@SequenceGenerator(name = "la", sequenceName = "la_seq")
	@Column(name = "id_la")
	private long id;
	
	@Column(name = "nm_la", nullable = false, length = 50, unique = true)
	private String nome;
	
	@Column(name = "ds_la", nullable = false, length = 50)
	private String descricao;
	
	@Column(name = "cd_vivo", nullable = false)
	private int codVivo;
	
	@Column(name = "cd_oi", nullable = false)
	private int codOi;
	
	@Column(name = "cd_claro", nullable = false)
	private int codClaro;
	
	@Column(name = "cd_tim", nullable = false)
	private int codTim;
	
	@Column(name = "cd_nextel", nullable = false)
	private int codNextel;
	
	@Column(name = "cd_ctbc", nullable = false)
	private int codCtbc;
	
	@Column(name = "tx_mercuri_url", nullable = false, length = 128)
	private String mercuriUrl;
	
	@Column(name = "tx_mercuri_serviceid", nullable = false)
	private int mercuriServiceId;
	
	@Column(name = "tx_mercuri_itemid", nullable = false)
	private int mercuriItemId;
	
	@Column(name = "tx_mercuri_username", nullable = false, length = 50)
	private String mercuriUsername;
	
	@Column(name = "tx_mercuri_password", nullable = false, length = 50)
	private String mercuriPassword;
	
	@Column(name = "cd_ativo", nullable = false)
	private int ativo;
	
	@Column(name = "dt_criacao", nullable = false)
	private Date dtCriacao;
	
	@Column(name = "dt_alteracao", nullable = false)
	private Date dtAlteracao;
	
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "parceiro_la",
		joinColumns=@JoinColumn(name = "id_la"),
		inverseJoinColumns=@JoinColumn(name = "id_parceiro"))
	private List<Parceiro> parceiros;

Tenho um método para exibir uma lista de todos os parceiros segue meu método:

@Override
	@SuppressWarnings("unchecked")
	public List<Parceiro> findAll() {
		Session session = (Session) entityManager.getDelegate();
		Criteria crit = session.createCriteria(Parceiro.class);
		return crit.list();
	}

Porém se um parceiro possuir mais de um LA, na minha busca de todos os parceiros ele acaba trazendo o mesmo parceiro 2 ou mais vezes, dependendo do número de parceiros que estiver na tabela parceiro_la como se ele estivesse buscando de parceiro_la

segue o select gerado pelo hibernate:

select this_.id_parceiro as id1_28_1_, this_.cd_ativo as cd2_28_1_, this_.dt_alteracao as dt3_28_1_, this_.dt_criacao as dt4_28_1_, this_.nm_parceiro as nm5_28_1_, 
this_.nm_parceiro_performance as nm6_28_1_, this_.nu_retentativa as nu7_28_1_, this_.nu_timeschedule as nu8_28_1_, las2_.id_parceiro as id1_3_, la3_.id_la as id2_3_, 
la3_.id_la as id1_27_0_, la3_.cd_ativo as cd2_27_0_, la3_.cd_claro as cd3_27_0_, la3_.cd_ctbc as cd4_27_0_, la3_.cd_nextel as cd5_27_0_, la3_.cd_oi as cd6_27_0_, 
la3_.cd_tim as cd7_27_0_, la3_.cd_vivo as cd8_27_0_, la3_.ds_la as ds9_27_0_, la3_.dt_alteracao as dt10_27_0_, la3_.dt_criacao as dt11_27_0_, la3_.tx_mercuri_itemid as tx12_27_0_, 
la3_.tx_mercuri_password as tx13_27_0_, la3_.tx_mercuri_serviceid as tx14_27_0_, la3_.tx_mercuri_url as tx15_27_0_, la3_.tx_mercuri_username as tx16_27_0_, la3_.nm_la as nm17_27_0_ 
from Parceiro this_ left outer join parceiro_la las2_ on this_.id_parceiro=las2_.id_parceiro left outer join LA la3_ on las2_.id_la=la3_.id_la

Alguém já passou por isso?

Isso acontece por que o hibernate entende que cada registro relacionado ao parceiro em parceiro_la é um registro diferente.
Será preciso colocar aí alguma limitação, talvez group by.
Criteria tem um Restriction que retorna apenas registros únicos, mas não me recordo agora. É algo como o singleResult.

[quote=drsmachado]Isso acontece por que o hibernate entende que cada registro relacionado ao parceiro em parceiro_la é um registro diferente.
Será preciso colocar aí alguma limitação, talvez group by.
Criteria tem um Restriction que retorna apenas registros únicos, mas não me recordo agora. É algo como o singleResult.[/quote]
Outra coisa, suas classes estão com hashCode/equals implementados?
Se sim, tenta jogar o resultado dentro de um set ao invés de um List

Pessoal,

enfim resolvido!

no meu método findAll foi necessário adicionar uma linha:

crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

ficando assim:

@Override
@SuppressWarnings("unchecked")
public List<Parceiro> findAll() {
	Session session = (Session) entityManager.getDelegate();
	Criteria crit = session.createCriteria(Parceiro.class);
	crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
	return crit.list();
}

[quote=fabio.cbrandao]Pessoal,

enfim resolvido!

no meu método findAll foi necessário adicionar uma linha:

crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

ficando assim:

@Override @SuppressWarnings("unchecked") public List<Parceiro> findAll() { Session session = (Session) entityManager.getDelegate(); Criteria crit = session.createCriteria(Parceiro.class); crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); return crit.list(); } [/quote]
Isso, era o que eu estava tentando lembrar.
O problema de ficar sem mexer com algo por muitos meses é isso.

é drsmachado eu tentei pesquisando de tudo no google, como relacionamento ManyToMany, ai eu vi q vc colocou registros únicos e pesquisei no google “Registros únicos criteria” e BINGO…

[quote=fabio.cbrandao]é drsmachado eu tentei pesquisando de tudo no google, como relacionamento ManyToMany, ai eu vi q vc colocou registros únicos e pesquisei no google “Registros únicos criteria” e BINGO…
[/quote]
é que eu tive esse problema no primeiro projeto que participei.
Atualmente, como estou trabalhando apenas com comunicação java + cobol, quase não uso o bendito…

Boas aí, camarada