Estou bem perdido, tenho duas classes, uma associação N:N, então em um formulário eu passo o ID de um objeto, faço a procura deste objeto pelo Hibernate, procuro também o outro objeto e então faço a associação tudo em uma action, mas estou recebendo um erro que fala que já possuo sessão aberta, mas se fecho ele fala que esta fechada, sendo assim não sei resolver. Por favor, alguem pode me ajudar?
Erro
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)
Action
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 daofactory2 = new DaoFactory();
daofactory2.beginTransaction();
clube = daofactory2.getClubeDao().buscaById(Clube.class, (Long.parseLong(idClube)));
daofactory2.close();
//3
//Busca Campeonato
DaoFactory daofactory1 = new DaoFactory();
Campeonato campeonato = new Campeonato();
daofactory1.beginTransaction();
campeonato = daofactory1.getCampeonatoDao().buscaById(Campeonato.class, 1L);
List<Clube> clubes = new ArrayList<Clube>();
daofactory1.close();
//4
//Adiciona mais um clube ao campeonato
clubes = campeonato.getClubes();
clubes.add(clube);
campeonato.setClubes(clubes);
//5
//Atualiza Campeonato
DaoFactory daofactory = new DaoFactory();
daofactory.beginTransaction();
daofactory.getCampeonatoDao().atualiza(campeonato);
daofactory.commit();
daofactory.close();
//6
//Coloca a Lista de Clubes novamente na pagina listaClube.jsp
ArrayList CLUBES = new ArrayList();
output.setValue("clubes", clubes);
return SUCCESS;
}
}
pra vc fazer isso não prescisa recuperar os dois depois alterar um e salvar de novo, recupera só o campeonato, e adiciona o clube na lista dele, e manda salvar, o resto o hibernate faz pra vc…
OK, até comecei a fazer aqui, mas ai surgiu uma duvida. Eu recebo o idClube via post (apenas o id) então eu tenho que fazer a procura no BD para trazer todo o objeto e então setar o objeto clube que já existe no BD no objeto Campeonato. Se for isso não consigo fazer como você me explicou. Tem alguma segestão? Será que estou fazerndo errado as Classes ou o mapeamento? Vou mandar pra dar uma conferida
Campeonato
@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;
@ManyToMany ( cascade = CascadeType.ALL )
@JoinTable ( name = "campeonato_clube" )
private List<Clube> clubes;
public Long getIdCampeonato() {
return idCampeonato;
}
public void setIdCampeonato(Long idCampeonato) {
this.idCampeonato = idCampeonato;
}
public int getGruposCampeonato() {
return gruposCampeonato;
}
public void setGruposCampeonato(int gruposCampeonato) {
this.gruposCampeonato = gruposCampeonato;
}
public int getClubesCampeonato() {
return clubesCampeonato;
}
public void setClubesCampeonato(int clubesCampeonato) {
this.clubesCampeonato = clubesCampeonato;
}
public String getTipoCampeonato() {
return tipoCampeonato;
}
public void setTipoCampeonato(String tipoCampeonato) {
this.tipoCampeonato = tipoCampeonato;
}
public List<Clube> getClubes() {
return clubes;
}
public void setClubes(List<Clube> clubes) {
this.clubes = clubes;
}
}
@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 ( cascade = CascadeType.ALL , mappedBy = "clubes" )
@JoinTable ( name = "campeonato_clube" )
private List<Campeonato> campeonatos;
public int getNivelClube() {
return nivelClube;
}
public void setNivelClube(int nivelCluve) {
this.nivelClube = nivelCluve;
}
public Long getIdClube() {
return idClube;
}
public void setIdClube(Long idClube) {
this.idClube = idClube;
}
public String getPaisClube() {
return paisClube;
}
public void setPaisClube(String paisClube) {
this.paisClube = paisClube;
}
public String getEscudoClube() {
return escudoClube;
}
public void setEscudoClube(String escudoClube) {
this.escudoClube = escudoClube;
}
public String getNomeClube() {
return nomeClube;
}
public void setNomeClube(String nomeClube) {
this.nomeClube = nomeClube;
}
public List<Campeonato> getCampeonatos() {
return campeonatos;
}
public void setCampeonatos(List<Campeonato> campeonatos) {
this.campeonatos = campeonatos;
}
}
Fiz o que você sugeriu, porém fazendo assim eu só consigo adicionar 1 clube ao campeonato, o que eu queria era adicionar 1 clube, depois mais outro… e assim por diante.
Vou tentar explicar, no passo que eu numerei como 5, eu façoi uma busca da lista de clubes que já se encontram no campeonato e então adiciona mais o que trouxe do formulário. Se eu tirar esta linha ele funciona, mas só consigo colocar 1 clube no campeonato. Por favor, sugere algo?
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();
daofactory.beginTransaction();
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
List<Clube> clubes = new ArrayList<Clube>();
//5
//Traz a lista de clubes do campeonato
clubes = campeonato.getClubes(); //Com essa linha da erro
//6
//Adiciona o clube na lista
clubes.add(clube);
campeonato.setClubes(clubes);
//7
//Atualiza Campeonato
daofactory.getCampeonatoDao().atualiza(campeonato);
daofactory.commit();
daofactory.close();