Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Persistir duas tabelas relacionadas

Boa noite, na aula referente a login e logout foi colocado diretamente no banco de dados a relação entre o e-mail do usuário e o nome de sua role. Como cada informação está em tabelas diferentes ou seja a informação do relacionado aos dados do usuário encontra-se na tabela usuário e a informação relacionado as roles na tabela de role.

Estou desenvolvendo um form para cadastrar o login e tudo esta indo bem até o momento em descido implementar no formulário a opção de definir a role do usuário que esta sendo cadastrado

Ai vem a duvida, se a informação do usuário está salva na tabela de usuário vamos dizer que eu precise do e-mail do usuário para associar a role, porem essa role está em uma outra tabela

Ao usar a anotation @manytomany o Hibernete gerou um outra tabela Usuário_Role, como eu colocaria dentro dessa tabela o e-mail do usuário e role já que estão em tabelas diferentes.

segue abaixo classe UsuarioDAO

@Transactional
@Repository
public class UsuarioDAO {

    @PersistenceContext
    private EntityManager manager;

    public void adicionaUsuario(Usuario usuario){
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String hasSenha = passwordEncoder.encode(usuario.getSenha());
        usuario.setSenha(hasSenha);        
        manager.persist(usuario);
        }
    public List<Usuario> lista() {
        return manager.createQuery("select u from Usuario u", Usuario.class).getResultList();
    }
}

segue abaixo classe UsuarioController

@Controller
@RequestMapping("/usuarios")
public class UsuariosController {

    @Autowired
    private UsuarioDAO usuarioDAO;

    @RequestMapping(method=RequestMethod.POST)
    public ModelAndView grava(@Valid Usuario usuario, BindingResult result,
                                RedirectAttributes redirectAttributes ){
        if(result.hasErrors()){
            return form(usuario);
        }
        usuarioDAO.adicionaUsuario(usuario);
        redirectAttributes.addFlashAttribute("sucesso", "Usuario "+usuario+" cadastrado com sucesso!");

        return new ModelAndView("redirect:usuarios");
    }

    @RequestMapping("/form/cadastro")
    public ModelAndView form(Usuario usuario) {
        ModelAndView modelAndView = new ModelAndView("usuarios/form-cad-usuario");
        return modelAndView;
    }

    @RequestMapping(method=RequestMethod.GET)
    public ModelAndView lista(){
        List<Usuario> usuarios = usuarioDAO.lista();
        ModelAndView modelAndView = new ModelAndView("usuarios/lista-usuarios");
        modelAndView.addObject("usuarios", usuarios);

        return modelAndView;
    }

}

segue abaixo classe Usuario

package br.com.clienteoculto.models;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Usuario {


    @Id
    private String email;
    private String senha;
    private String nome;
    @ManyToMany(fetch=FetchType.EAGER)
    private List<Role> role = new ArrayList<Role>();


    public List<Role> getRole() {
        return role;
    }

    public void setRole(List<Role> role) {
        this.role = role;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

}

segue abaixo classe Role

package br.com.clienteoculto.models;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Role{

    @Id 
    private String previlegios;

    public String getPrevilegios() {
        return previlegios;
    }

    public void setPrevilegios(String previlegios) {
        this.previlegios = previlegios;
    }


}

segue abaixo jsp cadastro de usuarios

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8">
    <title>Cliente Oculto</title>
    </head>
    <body>
        <h1>Cadastro Clientes</h1>

        <form:form action="${spring:mvcUrl('UC#grava').build()}" method="post" commandName="usuario">
            <div>
                <label for="nome">Nome</label> 
                <form:input path="nome"/>
                <form:errors path="nome" />
            </div>

            <div>
                <label for="email">E-mail</label>
                <input type="email" name="email"/>
                <form:errors path="email" />
            </div>

            <div>
                <label for="senha">Senha</label>
                <input type="password" name="senha"/>
                <form:errors path="senha" />
            </div>

            <div>
                <form:radiobutton path="roles.previlegios" value="ADMIN" label="Administrador" />
                <form:radiobutton path="roles.previlegios" value="OPERADOR" label="Operador" />
                <form:errors path="roles" />
            </div>

            <div>
                <button type="submit">Cadastrar</button>
            </div>
        </form:form>
    </body>
</html>

fazendo uma analogia o que pretendo fazer é:

insert  into Usuario(email,senha) values ("wilker@gmail",1234);
insert into Role(nome) values("ADMIN");
insert into Usuario_Role(email_usuario,nome_role) values ("wilker@gmail","ADMIN")

A ideia é executar essas querys no momento em que submeter o formulário de cadastro de usuário.

Desde já agradeço a ajuda!

2 respostas
solução!

Fala Wilker, tudo bem ?

Lembre-se que estamos usando a JPA com o Hibernate. Uma vez utilizando uma solução ORM a ideia é que a gente desapegue das tabelas do mundo relacional e pense apenas nos objetos. A implementação da JPA se encarrega do resto.

Pois bem. Partindo desse pressuposto, vamos analisar algumas coisas. Tanto sua classe Usuario quanto sua classe Role já são entidades devidamente mapeadas e relacionadas. O Hibernate já sabe que a transição do estado desses objetos para o mundo relacional já tem uma série de detalhes, como por exemplo a tabela de relacionamento gerada.

Dessa forma podemos programar de maneira simples. Você poderia na action do controller que salva os usuários - antes de chamar o usuarioDAO.adicionaUsuario(usuario) - recuperar do banco o objeto Role correspondente à escolha que o usuário fez na página (com um roleDao.buscaPorNome(nomeDaRole), por exemplo). Uma vez que o objeto role já foi recuperado pela JPA (ele encontra-se no estado gerenciado) poderia simplesmente adicionar a referencia do mesmo ao usuário.

Agora, quando o usuarioDAO.adicionaUsuario(usuario) for invocado o usuário ja contém uma referência de role conhecida pela JPA, que por sua vez já adequa os inserts para tudo funcionar.

Espero ter ajudado. Abraço!

Opa Rafael tudo certo e contigo?

Acredito ter entendido, vou tentar implementar

obrigado pela força!!