Atualizar registros com ManytoMany no Hibernate

12 respostas
W

Olá pessoal,

Eu criei um relacionamento manytomany com o hibernate. Tenho duas classes; a classe clube e a classe campeonato, um capeonato tem vários clubes e um clube pode estar em vários campeonatos.
Consigo criar uma lista de clubes e setar no campeonato usando campeonato.setClubes(listadeClubes), fiz o commit e até ai OK. Mas agora eu quero por exemplo é excluir um clube deste campeonato, ou até adicionar um outro. Como faço isso?
Tentei add um clube fazendo assim, mas não deu certo

List<Clube> clubes = new ArrayList<Clube>();
		//
		//Traz a lista de clubes do campeonato
		clubes = campeonato.getClubes();  //Com essa linha da erro ao fazer commit
		//
		//Adiciona mais um clube na lista
		clubes.add(clube);
		//Seta a lista no campeonato
		campeonato.setClubes(clubes);

Abaixo seguem as classes e o mapeamento.

@javax.persistence.Entity
public class Campeonato implements java.io.Serializable{
	
	private static final long serialVersionUID = 1L;
	@javax.persistence.Id
	@javax.persistence.GeneratedValue
	private Long idCampeonato;
	@NotNull
	private int gruposCampeonato;
	@NotNull
	private int clubesCampeonato;
	@NotEmpty
	private String tipoCampeonato;

	@CollectionOfElements
	@JoinTable(    
			name="campeonato_clube",    
			joinColumns={@JoinColumn(name="idCampeonato")},    
			inverseJoinColumns={@JoinColumn(name="idClube")}    
	)  
	private List<Clube> clubes;
//     Gets and Sets
@javax.persistence.Entity
public class Clube implements java.io.Serializable{

	private static final long serialVersionUID = 1L;
	@javax.persistence.Id
	@javax.persistence.GeneratedValue
	private Long idClube;
	@NotEmpty
	private String nomeClube;
	@NotNull
	private int nivelClube;
	@NotEmpty
	private String paisClube;
	private String escudoClube;
	
	@ManyToMany (mappedBy = "clubes" ) 
	private List<Campeonato> campeonatos;
//     Gets and Sets

Grato,
Wallfox

12 Respostas

V
Torne o relacionamento entre as entidades bidirecional, e quando for adicionar um novo clube, salve os dois lados:
// o campeonato conhece o clube
campeonato.getClubes().add(clube);

// e aqui o clube conhece o novo campeonato, o relacionamento se tornou bidirecional
clube.getCampeonatos.add(campeonato);

// exemplo de quando for salvar
session.beginTransaction();
session.saveOrUpdate(campeonato);
session.saveOrUpdate(clube);
session.getTransaction().commit();
Vê se resolve! Flw! :thumbup:
E

Cara, sempre que fiz isso apenas anotei os atributos com @ManyToMany e o mappedBy. Ai vc manda um SchemaExport ele cria uma tabela intermediaria para fazer a relação.

W
von.juliano:
Torne o relacionamento entre as entidades bidirecional, e quando for adicionar um novo clube, salve os dois lados:
// o campeonato conhece o clube
campeonato.getClubes().add(clube);

// e aqui o clube conhece o novo campeonato, o relacionamento se tornou bidirecional
clube.getCampeonatos.add(campeonato);

// exemplo de quando for salvar
session.beginTransaction();
session.saveOrUpdate(campeonato);
session.saveOrUpdate(clube);
session.getTransaction().commit();
Vê se resolve! Flw! :thumbup:

Ok. Como faço para tornar o relacionamento bidirecional? No mapeamento que fiz não é o correto?

Grato,
Wallfox

W

egamorim:
Cara, sempre que fiz isso apenas anotei os atributos com @ManyToMany e o mappedBy. Ai vc manda um SchemaExport ele cria uma tabela intermediaria para fazer a relação.

OK. com essa anotação ele também cria a tabela intermediária, mas estou com o problema que expliquei. Como ficaria o mapeamento?

Grato,
Wallfox

E

Cara, pelo que sei, assim deveria funcionar:

public class Campeonato implements java.io.Serializable{  
       
     private static final long serialVersionUID = 1L;  
     @javax.persistence.Id  
     @javax.persistence.GeneratedValue  
     private Long idCampeonato;  
     @NotNull  
     private int gruposCampeonato;  
     @NotNull  
     private int clubesCampeonato;  
     @NotEmpty  
     private String tipoCampeonato;  
   
     @ManyToMany   
     private List<Clube> clubes;  
 //     Gets and Sets

e

public class Clube implements java.io.Serializable{  
   
     private static final long serialVersionUID = 1L;  
     @javax.persistence.Id  
     @javax.persistence.GeneratedValue  
     private Long idClube;  
     @NotEmpty  
     private String nomeClube;  
     @NotNull  
     private int nivelClube;  
     @NotEmpty  
     private String paisClube;  
     private String escudoClube;  
       
     @ManyToMany (mappedBy = "clubes" )   
     private List<Campeonato> campeonatos;  
 //     Gets and Sets

e

// o campeonato conhece o clube  
 campeonato.getClubes().add(clube);  
   
 // e aqui o clube conhece o novo campeonato, o relacionamento se tornou bidirecional  
 clube.getCampeonatos.add(campeonato);  
   
 // exemplo de quando for salvar  
 session.beginTransaction();  
 session.saveOrUpdate(campeonato);  
 session.saveOrUpdate(clube);  
 session.getTransaction().commit();
V

Sobre tornar o relacionamento bidirecional eu não me referia ao mapeamento, mas à associação entre os objetos. Com a linha:

campeonato.getClubes().add(clube);O campeonato tem conhecimento do clube. Esse relacionamento está unidirecional nesse momento. Quando você faz:

clube.getCampeonatos.add(campeonato);Você relaciona de forma bidirecional, porque não só o campeonato conhece o clube, como o clube conhece o campeonato.

Blz? Flw! :thumbup:

W

Olá pessoal,

Tentei fazer como explicado por vocês, porém recebi a seguinte exception:

javax.servlet.ServletException: Exception while invoking action selecionaClube: null / java.lang.reflect.InvocationTargetException / Illegal attempt to associate a collection with two open sessions / org.hibernate.HibernateException
	org.mentawai.core.Controller.service(Controller.java:661)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Segue abaixo como estou tentando fazer:

public class selecionaClubeAction extends BaseAction{
	public String execute() throws Exception {
		//1
		//Recebe idClube do clube selecionado no formulario
		String idClube = input.getString("idClube");
		//2
		//Busca o clube 
		Clube clube = new Clube();
		DaoFactory daofactory = new DaoFactory();
		clube = daofactory.getClubeDao().buscaById(Clube.class, (Long.parseLong(idClube)));
		//3
		//Busca Campeonato
		Campeonato campeonato = new Campeonato();
		campeonato = daofactory.getCampeonatoDao().buscaById(Campeonato.class, 1L);
		//4
		//Adiciona mais um clube ao campeonato
		campeonato.getClubes().add(clube);
		//adiciona o campeonato no clube
		clube.getCampeonatos().add(campeonato);
		
		daofactory.beginTransaction();
		daofactory.getCampeonatoDao().atualiza(campeonato);
		daofactory.commit();
		daofactory.close();

		return SUCCESS;
	}
}

Grato,
Wallfox

W

Pessoal,

Por favor, sera que alguem ai pode me ajudar?

Grato,
Wallfox

W

Alguém para me ajudar?!?!?!?

V

cara eu nao sei nada do teu ambiente mas parece que vc tah abrindo duas sessions ou 1 session nem acabou e ja tem outra querendo tocar nas coisas da primeira

vc tem um session filter que faz o OPEN SESSION IN VIEW?

flw

W

Maravilha!!!
Consegui encontrar o erro. Estava no método BuscaByID.

Grato,
Wallfox

A

Amigo, estou com o mesmo problema!

Você poderia postar seu codigo?

Grato.

Criado 21 de julho de 2009
Ultima resposta 1 de set. de 2009
Respostas 12
Participantes 5