Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

Utilizar duas entidades JAVA

Pessoal, queria usar duas entidades, porem não estou conseguindo receber os parametros na controller, na verdade não sei muito bem como construir o metodo, se alguem puder me ajudar, obrigado..

MODELS:

@Entity
public class Atleta {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String nome;
    private String dataNascimento;
    private String tipoDeficiencia;
    private String modalidade;

    @OneToMany
    private List<AtletaDocumento> atletaDocumento;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

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

    public String getDataNascimento() {
        return dataNascimento;
    }

    public void setDataNascimento(String dataNascimento) {
        this.dataNascimento = dataNascimento;
    }

    public String getTipoDeficiencia() {
        return tipoDeficiencia;
    }

    public void setTipoDeficiencia(String tipoDeficiencia) {
        this.tipoDeficiencia = tipoDeficiencia;
    }

    public String getModalidade() {
        return modalidade;
    }

    public void setModalidade(String modalidade) {
        this.modalidade = modalidade;
    }

}
@Entity
public class AtletaDocumento {

    @ManyToOne
    private Atleta atleta;
    private String tipoDocumento;
    @Id
    private String numeroDocumento;

    public Atleta getAtleta() {
        return atleta;
    }
    public void setAtleta(Atleta atleta) {
        this.atleta = atleta;
    }
    public String getTipoDocumento() {
        return tipoDocumento;
    }
    public void setTipoDocumento(String tipoDocumento) {
        this.tipoDocumento = tipoDocumento;
    }
    public String getNumeroDocumento() {
        return numeroDocumento;
    }
    public void setNumeroDocumento(String numeroDocumento) {
        this.numeroDocumento = numeroDocumento;
    }



}

CONTROLLERS:

@Controller
public class AtletaController {

    @Autowired
    private AtletaRepository atletaRepository;

    @Autowired
    private AtletaDocumentoRepository adr;

    @Autowired
    private AtletaDAO atletaDao;

    @RequestMapping("formAtleta") // chama o formulario atleta
    public String form() {
        return "formAtleta";
    }

    @RequestMapping("cadastrarAtleta")
    public String salva(Atleta atleta, AtletaDocumento atletaDocumento) {
        atletaDocumento.setAtleta(atleta);
        adr.save(atletaDocumento);
        atletaRepository.save(atleta);
        return "redirect:formAtleta";
    }

    @RequestMapping("excluirAtleta")
    public String excluir(Atleta atleta) {

        atletaDao.delete(atleta.getId());
        return "redirect:listarAtletas";
    }

    @RequestMapping("listarAtletas")
    public ModelAndView listaAtletas() {
        ModelAndView mv = new ModelAndView("listaAtletas");
        Iterable<Atleta> atletas = atletaRepository.findAll();
        mv.addObject("atleta", atletas);
        return mv;
    }

    @RequestMapping("mostrarAtleta")
    public String mostra(Integer id, Model model) {
        model.addAttribute("atleta", atletaDao.findOne(id));
        return "alteraAtleta";
    }

    @RequestMapping("alteraAtleta")
    public String altera(Atleta atleta) {
        atletaDao.alterar(atleta);
        return "redirect:listarAtletas";
    }



}

DAO:

@Repository
@Transactional
public class AtletaDAO {

    @PersistenceContext
    private EntityManager manager;

    public Atleta findOne(Integer id) {
        return manager.find(Atleta.class, id);
    }

    public void delete(Integer id) {

        manager.remove(findOne(id));

    }

    public void alterar(Atleta atleta) {
        manager.merge(atleta);
    }

}

REPOSITORY:

public interface AtletaRepository extends JpaRepository<Atleta, String> {

    Atleta findById(Integer id);


}
8 respostas

Opa, Bruno!

Na Aula 7 do curso de JPA, o assunto é exatamente o que você precisa: mapeamentos bidirecionais.

Para que não seja criada uma tabela de relacionamento, você precisa usar a propriedade mappedBy da anotação @OneToMany, indicando o nome do atributo no outro lado do relacionamento.

@Entity
public class Atleta {

  //...  

  @OneToMany(mappedBy="atleta")
  private List<AtletaDocumento> atletaDocumento;

  //...  

}

Para receber no Controller os dados do Atleta, eu recomendo criar um objeto AtletaForm, que tem os dados e recebê-lo como parâmetro no método salva do AtletaController.

Essa ideia é melhor explicada nesse post: https://domineospring.wordpress.com/2018/04/23/sera-que-o-struts-1-estava-certo/

Alberto, eu estou com outro problema agora, caso puder me ajudar ficarei muito grato...

Estou com esta exception: object references an unsaved transient instance - save the transient instance before flushing : com.atletasCPB.model.AtletaDocumento.atleta -> com.atletasCPB.model.Atleta

Segue minhas classes:

METODO DA CONTROLLER:

    @RequestMapping("cadastrarAtleta")
    public String salva(Atleta atleta, AtletaDocumento atletaDocumento) {
        try {
            atletaDocumento.setAtleta(atleta);
            adr.save(atletaDocumento);
            atletaRepository.save(atleta);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }

        return "redirect:formAtleta";
    }

MODELS:

@Entity
public class Atleta {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String nome;
    private String dataNascimento;
    private String tipoDeficiencia;
    private String modalidade;

    @OneToMany(mappedBy="atleta")
    private List<AtletaDocumento> atletaDocumento;
@Entity
public class AtletaDocumento {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    private Atleta atleta;
    private String tipoDocumento;
    private String numeroDocumento;

FORMULARIO DE CADASTRO:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<c:import url="/WEB-INF/jsp/_comum/header.jsp" />
    <h2>Cadastro de Atletas</h2>
                <form method="post" action="cadastrarAtleta">
                    <div class="form-group">
                        <label for="nome">Nome:</label>
                        <input type="text" class="form-control" name="nome">
                      </div>
<!--                       <div class="form-group"> -->
<!--                         <label for="cpf">CPF:</label> -->
<!--                         <input type="text" class="form-control" name="cpf"> -->
<!--                       </div> -->
<!--                       <div class="form-group"> -->
<!--                         <label for="rg">RG:</label> -->
<!--                         <input type="text" class="form-control" name="rg"> -->
<!--                       </div> -->

                    <div>
                        <label for="tipoDocumento">Tipo de documento:</label>
                        <input type="text" class="form-control" name="tipoDocumento" >
                    </div>
                    <div>
                        <label for="numeroDocumento">Numero do documento:</label>
                        <input type="text" class="form-control" name="numeroDocumento" >
                    </div>
                    <div class="form-group">
                        <label for="dataNascimento">Data Nascimento:</label>
                        <input type="date" class="form-control" name="dataNascimento">
                      </div>
                          <div class="form-group">
                        <label for="tipoDeficiencia">Tipo Deficiencia:</label>
                        <input type="text" class="form-control" name="tipoDeficiencia">
                      </div>
                      <div class="form-group">
                        <label for="modalidade">Modalidade:</label>
                        <input type="text" class="form-control" name="modalidade">
                      </div>

                    <button type="submit" class="btn btn-default">Adicionar</button>
                </form>        

<c:import url="/WEB-INF/jsp/_comum/footer.jsp" />

Opa, Bruno.

Salve o Atleta antes de salvar o AtletaDocumento, porque essa segunda classe contém uma instância da primeira.

Ou seja, faça:

atletaRepository.save(atleta); //antes

atletaDocumento.setAtleta(atleta);
adr.save(atletaDocumento);

Um objeto no estado Transient é um objeto que não está representado no BD, ou seja não tem id.

Para que você o coloque num relacionamento @ManyToOne é necessário que ele esteja no estado Managed, ou seja, que tenha sido inserido no BD.

Poxa, deu certo Alberto, e no caso pra mim fazer a listagem na jsp ???

Controller:

    @RequestMapping("listarAtletas")
    public ModelAndView listaAtletas() {
        ModelAndView mv = new ModelAndView("listaAtletas");
        Iterable<Atleta> atletas = atletaRepository.findAll();
        mv.addObject("atleta", atletas);
        return mv;
    }

No Controller, é isso mesmo. Em termos de qualidade de código, eu mudaria uma coisa: colocaria atletas e não atleta no mv.addObject.

Ficaria então:

 Iterable<Atleta> atletas = atletaRepository.findAll();
mv.addObject("atletas", atletas);

Na JSP, você monta uma tabela com algo parecido com:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<c:import url="/WEB-INF/jsp/_comum/header.jsp" />

    <h2>Listagem de Atletas</h2>
<table>
              <tr>
                  <th>Id</th>
                  <th>Nome</th>
                  <th>Data de Nascimento/th>
                  <th>Tipo de Deficiência</th>
                  <th>Modalidade</th>
              </tr>
              <c:forEach items="${atletas}" var="atleta">
                  <tr>
                      <td>${atleta.id}</td>
                      <td>${atleta.nome}</td>
                      <td>${atleta.dataNascimento}</td>
                      <td>${atleta.tipoDeficiencia}</td>
                      <td>${atleta.modalidade}</td>
                  </tr>
              </c:forEach>
          </table>
<c:import url="/WEB-INF/jsp/_comum/footer.jsp" />

Me desculpa, nesse tempo chamei voce de Alberto rsrs e sim seu nome é Alexandre...

Porém minha duvida é referente as duas entidaeds, no ATLETA, ATLETADOCUMENTO...

Como eu iria interar na jsp na table... E como seria no controler com modelAndView... Tem como enviar dois objetos ?

solução

Tranquilo, Bruno! hehe

Acho que a melhor coisa é fazer uma listagem de Documentos e colocar o dado do Atleta. Algo como:

${document.atleta.nome}

Muito obrigado Alexandre, você me ajudou muito... Até mais... um abraço !!!