Hibernate Many to Many 3 entidades

Boa Noite,

Galera estou começando com Hibernate e estou com algumas dúvidas quanto a uma modelagem que fiz, eu queria fazer um relacionamento many to many onde a tabela de ligação também seja uma entidade.

Minha modelagem ficou assim:

import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

import br.com.caelum.vraptor.ioc.Component;

@Entity
@Component
public class Championship {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	@NotEmpty
	@NotNull
	@Length(min = 10, max = 50)
	@Column(length = 50)
	private String description;

	@OneToMany(fetch=FetchType.LAZY, mappedBy="championship")
	private Set<ChampionshipEnrolled> championshipEnrolled;

       ...
}
import java.io.Serializable;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;
import br.com.caelum.vraptor.ioc.Component;

@Entity
@Component
public class Associate implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	@Min(value = 1)
	@Max(value = 99999999)
	@Column()
	private Integer cr;

	@NotEmpty
	@Length(min = 10, max = 50)
	@Column(length = 50)
	private String name;

	@Email
	@NotEmpty
	@Length(min = 5, max = 50)
	@Column(unique = true, length = 50)
	private String email;

	@Column
	@NotNull
	@Enumerated(EnumType.ORDINAL)
	private AssociateType associateType;

	@Column
	private Boolean adminAccess;

	@Length(min = 5, max = 50)
	@Column(length = 50)
	private String password;
	
	@OneToMany(fetch=FetchType.LAZY, mappedBy="associate")
	private Set<ChampionshipEnrolled> championshipEnrolled;
	
	public Long getId() {
		return id;
	}

       ...
}
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import br.com.caelum.vraptor.ioc.Component;

@Entity
@Component
public class ChampionshipEnrolled implements Serializable {
	private static final long serialVersionUID = -1275977111673169430L;

	@Id
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(nullable=false)
	private Championship championship;
	
	@Id
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(nullable=false)
	private Associate associate;

       ...
}

Dúvidas:

1- Estão corretas as anotações para realizar esse relacionamento? A primeira vista eu creio que sim, pois o hibernate criou as tabelas do jeito que eu queria no BD.
2- É usual utilizar esse tipo de modelagem? Pensei dessa maneira para facilitar na hora de persistir os dados pois serão em 3 etapas diferentes, cadastra campeonato, cadastra associados e depois associa campeonatos com associados. Não sei se minha idéia está de acordo.

3- E a maior dúvida de todas é que eu gostaria de retornar uma lista de ChampionshipEnrolled filtrando por id de championship e por nome de associado, minha primeira idéia foi a seguinte:

Criteria criteria = session.createCriteria(ChampionshipEnrolled.class);
criteria.add(Restrictions.eq("championship.id", (long)1));
criteria.add(Restrictions.ilike("associate.name", "teste", MatchMode.ANYWHERE));

Porém, isso não funciona e me retorna o seguinte erro:

org.hibernate.QueryException: could not resolve property: associate.name of: br.com.tirocerto.model.ChampionshipEnrolled

E minha segunda tentativa foi:

Criteria criteria = session.createCriteria(ChampionshipEnrolled.class);
criteria.createAlias("associate", "associateAlias");
criteria.add(Restrictions.eq("championship.id", championshipId));
criteria.add(Restrictions.ilike("associateAlias.name", nome, MatchMode.ANYWHERE));

Que me retorna o seguinte erro:

org.hibernate.exception.GenericJDBCException: O identificador de várias partes &quot;associatea1_.name&quot; não pôde ser associado.

Alguém podería me ajudar a resolver esse problema?

Agradecido desde já.

CaBeLoRoX

Seguinte o Hibernet faz isto direto em uma das classes que você criou não é necessário criar uma classe para o relacionamento, vc faz a declaração Many to Many direto, desde que a tabela de relacionamento só tenha os Ids das que ira relacionar.

a declaração inclui em uma das Classes como exemplo:

//no caso este código vai na classe Championship
@ManyToMany
@JoinTable(name = “ChampionshipEnrolled”,
//nome da tabela no banco de dados
// este join relaciona com a tabela Championship o primeiro name é o campo da tabela relacionamento, o referencedColumnName é o nome no campo na tabela de Championship
joinColumns = @JoinColumn(name = “championship”, referencedColumnName = “championship”, nullable = false),
// dados da Tabela de Associados, para onde vai a relação, mesma coisa name é o nome do id da tabela de relação, o referencedColumnName é o id da tabela de associados.
inverseJoinColumns = @JoinColumn(name = “associate”, referencedColumnName = “associate”, nullable = false) )
private Set associates= new HashSet(0);

Entao no código acima quando acessar o objeto Championship consegue dar um getAssociates.

// este codigo va na casse Associate, faz uma referencia pelo nome digitado na classe Championship, e ai consegue pegar todos os dados com um getChampionships
@ManyToMany(mappedBy=“associates”)
private Set championships = new HashSet(0);

OBS: tem que gerar os Getter e Seters
Entao quando vc deseja pegar todos os associates com Championship vc digita Associate.getChampionships(); e ele ira retornar uma lista de championships Relacionados ao Associate.
e ao mesmo o inverso você traz o objeto Championships e faz um getAssociates();

Espero ter ajudado.

[quote]
1- Estão corretas as anotações para realizar esse relacionamento? A primeira vista eu creio que sim, pois o hibernate criou as tabelas do jeito que eu queria no BD.
2- É usual utilizar esse tipo de modelagem? Pensei dessa maneira para facilitar na hora de persistir os dados pois serão em 3 etapas diferentes, cadastra campeonato, cadastra associados e depois associa campeonatos com associados. Não sei se minha idéia está de acordo.

3- E a maior dúvida de todas é que eu gostaria de retornar uma lista de ChampionshipEnrolled filtrando por id de championship e por nome de associado, minha primeira idéia foi a seguinte: [/quote]
1 - Sim. Não analisei minunciosamente, mas parece estar tudo certo. Se o hibernate criou as tabelas corretamente, vai com fé.
2 - Sim.
3 - Não costumo usar criteria, mas uma query para retornar isso seria:

select ce from ChampionshipEnrolled ce join ce.associate a where a.name like ? and ce.champioship.id = ?