Estou com dificuldade em persistir dados em uma tabela com relacionamento @ManyToMany, quando uso @ManyToOne funciona tudo perfeito, porém com muitos para muitos não estou conseguindo. Possuo 3 tabelas no banco, cnai, unidades e unidades_cnai. Segue o código:
Classe com relacionamento @ManytoMany
@Entity
@Table(name = "unidades")
public class Unidade {
@Id
@GeneratedValue
private Integer id;
//Atributos
@ManyToMany
@JoinTable(name = "unidades_cnai")
private List<Cnai> cnai;
//Geters e Setters
public List<Cnai> getCnai() {
EntityManager em = new JPAUtil().getEntityManager();
CnaiDAO dao = new CnaiDAO(em);
return dao.getLista();
}
public void setCnai(List<Cnai> cnai) {
this.cnai = cnai;
}
}
Classe cnai
@Entity
@Table(name = "cnai")
public class Cnai {
@Id
@GeneratedValue
private Integer id;
private String codigo;
private String descricao;
private String GR;
//Geters e Setters
}
View de cadastro de unidades, local onde devo selecionar o Cnais a serem cadastrados
Quando clico o botão de gravar, grava uma nova unidade perfeitamente com tudo que foi passado pela view exeto o cnai, que não é gravado em lugar algum. Alguém pode ajudar?
Veja esse post, fala dos 3 relacionamentos. Com 10min de leitura você vai entender e vai conseguir fazer.[/quote]
O meu caso seria um relacionamento Unidirecional, de acordo com o Mini Livro que você me passou está correto (se não estou equivocado), apenas mudou os nomes em no lugar de person_dog ficou unidades_cnai, no lugar de person_id ficou unidades id e no lugar de dog_id ficou cnai_id.
Realizei algumas mudanças e boa noticia, está gravando na tabela unidades_cnai, porém ele grava TODOS os cnais e não apenas os que eu selecionei na minha lista na web. Alguma dica? Segue o código:
Unidades:
[code] @Entity @Table(name = “unidades”)
public class Unidade { @ManyToMany @JoinTable(name = “unidades_cnai”, joinColumns = @JoinColumn(name = “unidades_id”), inverseJoinColumns = @JoinColumn(name = “cnai_id”))
private List cnai;
public List<Cnai> getCnai() {
EntityManager em = new JPAUtil().getEntityManager();
CnaiDAO dao = new CnaiDAO(em);
return dao.getLista();
}
public void setCnai(List<Cnai> cnai) {
this.cnai = cnai;
}
}[/code]
Cnai (permanece sem modificações):
[code] @Entity @Table(name = “cnai”)
public class Cnai { @Id @GeneratedValue
private Integer id;
@RequestMapping("adicionaUnidade")
public String adicionaUnidade(@Valid Unidade unidade, BindingResult result,
Model model) {
EntityManager em = new JPAUtil().getEntityManager();
UnidadeDAO dao = new UnidadeDAO(em);
em.getTransaction().begin();
//regras de validação
unidade.setCnai(unidade.getCnai());
dao.getAdiciona(unidade);
em.getTransaction().commit();
em.close();
return "redirect:cadastroUnidade";
}
Fiz um teste para ver o retorno da lista, retornou vazia! As outras classes estão iguais
@RequestMapping("adicionaUnidade")
public String adicionaUnidade(@Valid Unidade unidade, BindingResult result,
Model model) {
EntityManager em = new JPAUtil().getEntityManager();
UnidadeDAO dao = new UnidadeDAO(em);
em.getTransaction().begin();
if (result.hasFieldErrors("sigla")) {
model.addAttribute("erro", unidade);
return "/planejamento/unidades_cadastrar";
} else if (result.hasFieldErrors("descricao")) {
model.addAttribute("erro", unidade);
return "/planejamento/unidades_cadastrar";
}
System.out.println("O VALOR DO CNAI ESTA AQUI: " + unidade.getCnai());
dao.getAdiciona(unidade);
em.getTransaction().commit();
em.close();
return "redirect:cadastroUnidade";
}
No console recebi: “O VALOR DO CNAI ESTA AQUI: []”
Cara, coloca try/catch e use o método printStrackTace no Catch para ver qual é o erro e onde está.
Pra ficar mais fácil, cria uma classe com um main e tente:
try{
Unidade unidade = new Unidade();
Cnai cnai = new Cnai();
unidade.getCnai().add(cnai);
//ou cria um método para adicionar direito
//unidade.adicionarCnai(cnai);
} catch(Exception e){
e.printSTrackTace();
}
Se não der erro, vá testando adicionar no banco, imprimiar a lista etc. Provavelmente é porque sua lista não está instanciada, olhando pelo código que você postou.
Cara eu acho que meu problema está no Cnai passado por uma lista na web ( ) , acho que ela não gera um objeto Cnai para ser persistido, tentei fazer unidade.getCnai().getId(), porém não era possível acessar o Id por ser um get de Lista, há uma forma de saber quais selecionei na minha interface e instanciá-los para então add a lista?
Com objeto Cnai podendo ser adicionado a lista creio que funcione perfeitamente!
Tentando fazer:
List<Cnai> cnai = new ArrayList<Cnai>();
cnai.add((Cnai) unidade.getCnai());
ao tentar salvar gera um erro falando que o Objeto passado não é um Cnai …
@RequestMapping("adicionaUnidade")
public String adicionaUnidade(@Valid Unidade unidade, BindingResult result,
Model model) {
EntityManager em = new JPAUtil().getEntityManager();
UnidadeDAO dao = new UnidadeDAO(em);
em.getTransaction().begin();
if (result.hasFieldErrors("sigla")) {
model.addAttribute("erro", unidade);
return "/planejamento/unidades_cadastrar";
} else if (result.hasFieldErrors("descricao")) {
model.addAttribute("erro", unidade);
return "/planejamento/unidades_cadastrar";
}
List<Cnai> cnai = new ArrayList<Cnai>();
cnai.add(unidade.getCnai().get(0));
System.out.println("O VALOR DO CNAI ESTA AQUI " + cnai);
dao.getAdiciona(unidade);
em.getTransaction().commit();
em.close();
return "redirect:cadastroUnidade";
}
Front end (acho que o problema ta por aqui em algum lugar)
Nesse caso uma gerência recebe uma unidade, funciona perfeitamente. Pensei em montar o Cnai no método que adiciona, porém por ser uma lista não é possível então não sei o que fazer!
Alguém tem ideia de como posso passar o Cnai da minha lista da interface web para minha lista do Java, ou resgatar os valores de ID para que eu possa fazer uma busca e monta-lo