[RESOLVIDO]Hibernate 3: Problema com cascade em save ou persist

Bom, acredito que a solução pro meu problema seja bem simples (ou assim espero).

O que quero fazer é simples: tenho uma tabela eleitor e uma tabela curso. Entre essas
tabelas, tenho uma tabela associativa cursos_eleitor. O que quero? Ao acionar o session.save()
no objeto do eleitor, que contém a lista de cursos que ele tem, o hibernate tambem fará a inserção
dos dados na tabela cursos_eleitor, através da lista de cursos. Seguem as classes em questão:

Classe de Eleitor

@Entity
@Table(name="eleitor")
public class Eleitor implements Serializable{
	private static final long serialVersionUID = -6226011868072777381L;
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="id_eleitor")
	private Integer idEleitor;
	@ManyToOne
	@JoinColumn(name="id_cidade")
	private Cidade cidade;
	@Column(name="el_nome")
	private String nome;
	...
        ...
        ...
	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@Cascade(value=CascadeType.SAVE_UPDATE)
	@JoinTable(name="cursos_eleitor",
	joinColumns = @JoinColumn(name="id_eleitor", referencedColumnName="id_eleitor"),
	inverseJoinColumns = @JoinColumn(name="id_curso", referencedColumnName="id_curso"))
	private List<Curso> listaCursos = new ArrayList<Curso>();
	@OneToMany(mappedBy="campanha", cascade = {javax.persistence.CascadeType.ALL})
	@Cascade(value=CascadeType.SAVE_UPDATE)
	private List<CampanhasEleitor> listaCampanhasEleitor = new ArrayList<CampanhasEleitor>();
	@OneToMany(mappedBy="eleitor", cascade = {javax.persistence.CascadeType.ALL})
	@Cascade(value=CascadeType.SAVE_UPDATE)
	private List<Experiencia> listaExperiencias = new ArrayList<Experiencia>();
	@Transient
	private DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	@Transient
	private DecimalFormat df = new DecimalFormat();
	
	//------------------------Getters e Setters--------------------------------

Classe de Curso

@Entity
@Table(name="curso")
public class Curso implements Serializable{
	private static final long serialVersionUID = -4067988173598135204L;
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="id_curso")
	private Integer idCurso;
	@Column(name="cs_nome")
	private String nome;
	@Column(name="cs_tipo")
	private String tipo;
	@Column(name="cs_inst")
	private String inst;
	@ManyToMany
	@JoinTable(name="cursos_eleitor",
	joinColumns = @JoinColumn(name="id_curso",referencedColumnName="id_curso"),
	inverseJoinColumns = @JoinColumn(name="id_eleitor", referencedColumnName="id_eleitor"))
	private List<Eleitor> listaEleitores = new ArrayList<Eleitor>();
	@Transient
	private String ntipo;
	@Transient
	private boolean marcado;
	@Transient
	private int index;

	//------------------------Getters e Setters--------------------------------

E finalmente a minha classe DAO:

public class EleitorDAO extends GenericDAO{
	Session session = getSession();
	
	@SuppressWarnings("unchecked")
	public List<Eleitor> all(){
		Query query = session.createQuery("from Eleitor");
		List<Eleitor> listaEleitores = query.list();
		return listaEleitores;
	}
	
	public Eleitor one(Eleitor ele){
		Query query = session.createQuery("from Eleitor e where e.idEleitor = ?");
		query.setInteger(0, ele.getIdEleitor());
		Eleitor Eleitor = (Eleitor) query.uniqueResult();
		return Eleitor;
	}
	
	public void update(Eleitor ele){
		session.update(ele);
		session.getTransaction().commit();
	}
	
	public void insert(Eleitor ele){
		session.persist(ele);
		session.getTransaction().commit();
	}
	
	public void delete(Eleitor ele){
		session.delete(ele);
		session.getTransaction().commit();
	}
}

Antes, ao executar o método insert da minha classe DAO, eu executava o session.save(), porém, em um tópico aqui do forum mesmo, o proprio usuario que fez o mesmo questionamento
que eu, disse ter resolvido o problema ao trocar o session.save() para session.persist(). Porém, isso não funcionou pra mim.

Se alguem puder ajudar, ficarei muito grato!

Deixa eu ver se entendi

Você quer persistir a lista de curso do eleitor certo?

Não se usa 2 tipo de cascade Jpa e Hibernate ao mesmo tempo

arrume seu código para isso

@ManyToMany(targetEntity=Curso.class, mappedBy="eleitor",fetch=FetchType.LAZY, cascade=CascadeType.ALL) @JoinTable(name="cursos_eleitor", joinColumns = @JoinColumn(name="id_eleitor", referencedColumnName="id_eleitor"), inverseJoinColumns = @JoinColumn(name="id_curso", referencedColumnName="id_curso")) private List<Curso> listaCursos;

esse mappedBy=“eleitor”

é um atributo que você tem quer la na sua classe Curso

Ex: private Eleitor eleitor;

Teste ai

Voce me disse que devo ter um objeto Eleitor na minha classe Curso, mas no lugar disso eu tenho uma lista de Eleitor, que ao meu ver,
seria mais adequado para um ManyToMany, não? Se eu colocar um objeto Eleitor lá, então cada curso só poderá ser vinculado à 1 eleitor, não?

Tentei fazer a alteração que você me disse, e recebi a seguinte excessão:

Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: br.com.jm.beans.Eleitor.listaCursos

desculpa ai eu so vi que era para persistir a lista

calma ai que eu vou ver suas classes

[quote=renangd]Tentei fazer a alteração que você me disse, e recebi a seguinte excessão:

Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: br.com.jm.beans.Eleitor.listaCursos[/quote]

vários cursos para vários eleitor (Eleitor que nome estranho, mas tudo bem)

como eu falei na primeira vez

você usou 2 tipo de cascade JPA e do Hibernate (isso não se faz)

Obs: Eleitor só tem que persistir a lista de cursos?

Imaginei que estranhariam isso mas…é porque é sistema interno de gabinete.

Então, como você pode ver na , eu tenho que persistir não só a listaCursos, mas também a listaExperiencias e
a listaCampanhasEleitor. Perguntei sobre a listaCursos mais porque a solução pra ela será a mesma pras outras.

Quanto ao seu questionamento de usar JPA e Hibernate ao mesmo tempo para fazer os cascades, eu também acho estranho,
e inicialmente eu estava utilizando somente a seguinte linha:

@ManyToMany(cascade = CascadeType.ALL)
	@JoinTable(name="cursos_eleitor",
	joinColumns = @JoinColumn(name="id_eleitor", referencedColumnName="id_eleitor"),
	inverseJoinColumns = @JoinColumn(name="id_curso", referencedColumnName="id_curso"))
	private List<Curso> listaCursos = new ArrayList<Curso>();

Porém, ao entrar em um topico do forum stackoverflow, o sujeito estava instruindo alguem com o mesmo problema ao “reforçar”
a definição de cascade com a annotation do Hibernate. Achei estranho, mas, eu tentei pra ver se funcionaria.

pra começar

você criou @joinColumns (Curso_eleitor)nas duas entidades só mudando o id em ambas
isso não pode

delete o joinColumns da entidade curso deixando apenas la no eleitor

Sem resultados, não me gerou excessões, mas também não resolveu.

deleto?

calma não termino ainda precisa arruma algumas coisas

Descobri o que era, fico até envergonhado…

Era simplesmente porque as listas não estão chegando ao meu DAO, meu objeto Eleitor chega com as respectivas
listas vazias, então, achei o problema, e ao rodar a aplicação, recebi umas excessão reclamando da redundância de
anotações para cascade, como você tinha me alertado anteriormente.

Muito obrigado pelo seu tempo cara!
E me desculpa pela lezeira de não verificar se as listas estavam mesmo populadas.

carinha faz parte…do aprendizado

é errando que se aprende

É isso aí…valeu!