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

Repeated column in mapping for entity: br.com.alura.modelo.loja.Produto column: categoria_id (should be mapped with insert="false" update="false")

Classe CadastroDeProdutoJava
package br.com.alura.modelo.teste;

import br.com.alura.dao.CategoriaDAO;
import br.com.alura.dao.ProdutoDAO;
import br.com.alura.modelo.Categoria;
import br.com.alura.modelo.loja.Produto;
import util.JPAUtil;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class CadastroDeProduto {
     public static void main(String[] args) {
          Categoria celulares = new Categoria("celulares");

          //criando um objeto e setando as informações dele  --- da linha 12 até a 15 eu estou simulando um usuario
          Produto celular = new Produto("Iphone 14","129 gb",1, celulares);


        // a loja_virtual  peguei do persistence unit
        //  EntityManagerFactory factory = Persistence.createEntityManagerFactory("loja_virtual");
         // EntityManager em = factory.createEntityManager();

          EntityManager em = JPAUtil.getEntityManager();
          ProdutoDAO produtoDao = new ProdutoDAO(em);
          CategoriaDAO categoriaDAO = new CategoriaDAO(em);

          em.getTransaction().begin();

         // em.persist(celular);  vai deixar de ser essa linha para ser a de baixo
          categoriaDAO.cadastrar(celulares);// salvei a categoria primeiro e depois o produtos
          produtoDao.cadastrar(celular);

          em.getTransaction().commit();
          em.close();
     }

}

Classe CategoriaDao

package br.com.alura.dao;

import br.com.alura.modelo.Categoria; import br.com.alura.modelo.loja.Produto;

import javax.persistence.EntityManager;

public class CategoriaDAO {

 private EntityManager em;    // ja com atributo
public CategoriaDAO(EntityManager em){  // construtor
     this.em = em;
}

public  void cadastrar(Categoria categoria){  // metodo que vai cadastrar um produto utilizando a JPA
     this.em.persist(categoria);  //

}

}

Classe Categoria

14 respostas

Classe Categoria

package br.com.alura.modelo;

import javax.persistence.*;

@Entity
@Table(name = "categorias")
public class Categoria {


     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)  // como valor é gerado da chave primaria
     private Long id;
     private String nome;

     public Categoria(String nome) { // CONSTRUTOR SÓ DO NOME, POIS ID É GERADO AUTOMARICAMENTE PELO BANCO DE DADOS
          this.nome = nome;
     }

     public String getNome(){
     return nome;
     }

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

     public Long getId() {
          return id;
     }

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

Classe Produto

package br.com.alura.modelo.loja;
import br.com.alura.modelo.Categoria;

import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDate;

// @Entity é  anotação da JPA dizendo que é uma entidade da Classe produto que está mapeando uma tabela no banco de dados
@Entity
@Table(name = "produto")
public class Produto {

          @Id  // chave estrangeira
          @GeneratedValue(strategy = GenerationType.IDENTITY)  // como valor é gerado da chave primaria
         private  Long id;
         private String nome;
         private String descricao;
         private Integer categoria_id;
         private LocalDate dataCadastro = LocalDate.now();

     @ManyToOne
         private Categoria categoria;

          public Produto(String nome, String descricao, int categoria_id, Categoria categoria) { // criando um construtor
          this.nome = nome;
          this.descricao = descricao;
          this.dataCadastro = dataCadastro;
          this.categoria_id = categoria_id;
     }


     public Long getId(){
          return  id;
     }

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

     public String getNome() {
          return nome;
     }

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

     public String getDescricao() {
          return descricao;
     }

     public void setDescricao(String descricao) {
          this.descricao = descricao;
     }

     public Integer getCategoria_id() {
          return categoria_id;
     }

     public void setCategoria_id(Integer categoria_id) {
          this.categoria_id = categoria_id;
     }

     public LocalDate getDataCadastro() {
          return dataCadastro;
     }

     public void setDataCadastro(LocalDate dataCadastro) {
          this.dataCadastro = dataCadastro;
     }
}

Estou recebendo esse erro, alguém pode auxiliar, tentei de tudo e nada

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: br.com.alura.modelo.loja.Produto column: categoria_id (should be mapped with insert="false" update="false") at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862) at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880) at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902) at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634) at org.hibernate.mapping.RootClass.validate(RootClass.java:267) at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:354) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ... 5 more

Oi!

Remove esse atributo da sua classe Produto:

private Integer categoria_id;

Fiz o que vc passou, porém onde estou chamando a categoria_id fica em vermelho, pois foi apagada da classe produto, nesse caso o que faz?

Apaguei tudo que era relacionado ao atributo da categoria_id e fica dando exception

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Tem que apagar em todos os lugares que estavam utilizando esse atributo. Construtor, metodos getter e setters, etc.

E nesse caso vai ficar null mesmo a categoria_id na tabela? Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Os códigos devem ficar assim:

@Entity
@Table(name = "produtos")
public class Produto {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private  Long id;
    private String nome;
    private String descricao;
    private LocalDate dataCadastro = LocalDate.now();

    @ManyToOne
    private Categoria categoria;

    public Produto(String nome, String descricao, Categoria categoria) {
        this.nome = nome;
        this.descricao = descricao;
        this.categoria = categoria;
    }

    public Long getId() {
        return  id;
    }

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

    public String getNome() {
        return nome;
    }

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

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public Categoria getCategoria() {
        return categoria;
    }

    public void setCategoria(Categoria categoria) {
        this.categoria = categoria;
    }

    public LocalDate getDataCadastro() {
        return dataCadastro;
    }

    public void setDataCadastro(LocalDate dataCadastro) {
        this.dataCadastro = dataCadastro;
    }
}
@Entity
@Table(name = "categorias")
public class Categoria {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String nome;

    public Categoria(String nome) {
        this.nome = nome;
    }

    public String getNome() {
        return nome;
    }

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

    public Long getId() {
        return id;
    }

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

E a classe com o método main:

public class CadastroDeProduto {
    
    public static void main(String[] args) {
        Categoria celulares = new Categoria("celulares");
        Produto celular = new Produto("Iphone 14", "129 gb", celulares);
        
        EntityManager em = JPAUtil.getEntityManager();
        ProdutoDAO produtoDao = new ProdutoDAO(em);
        CategoriaDAO categoriaDAO = new CategoriaDAO(em);
        
        em.getTransaction().begin();

        categoriaDAO.cadastrar(celulares);
        produtoDao.cadastrar(celular);

        em.getTransaction().commit();
        em.close();
    }
}

E os proximos produtos serao salvos com a categoria correta.

Fiz exatamente conforme está o que vc mandou, porém fica dando uma exception agora

Classe Produto



@Entity
@Table(name = "produto")
public class Produto {

          @Id  // chave estrangeira
          @GeneratedValue(strategy = GenerationType.IDENTITY)  // como valor é gerado da chave primaria
         private  Long id;
         private String nome;
         private String descricao;
         private LocalDate dataCadastro = LocalDate.now();

     @ManyToOne
         private Categoria categoria;

          public Produto(String nome, String descricao, Categoria categoria) { // criando um construtor
          this.nome = nome;
          this.descricao = descricao;
          this.categoria = categoria;

     }


     public Long getId(){
          return  id;
     }

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

     public String getNome() {
          return nome;
     }

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

     public String getDescricao() {
          return descricao;
     }

     public void setDescricao(String descricao) {
          this.descricao = descricao;
     }

     public Categoria getCategoria() {
          return categoria;
     }

     public void setCategoria(Categoria categoria) {
          this.categoria = categoria;
     }

     public LocalDate getDataCadastro() {
          return dataCadastro;
     }

     public void setDataCadastro(LocalDate dataCadastro) {
          this.dataCadastro = dataCadastro;
     }
}




Categoria

package br.com.alura.modelo;

import javax.persistence.*;

@Entity
@Table(name = "categorias")
public class Categoria {


     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)  // como valor é gerado da chave primaria
     private Long id;
     private String nome;

     public Categoria(String nome) { // CONSTRUTOR SÓ DO NOME, POIS ID É GERADO AUTOMARICAMENTE PELO BANCO DE DADOS
          this.nome = nome;
     }

     public String getNome(){
     return nome;
     }

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

     public Long getId() {
          return id;
     }

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

CadastroDeProduto

package br.com.alura.modelo.teste;

import br.com.alura.dao.CategoriaDAO;
import br.com.alura.dao.ProdutoDAO;
import br.com.alura.modelo.Categoria;
import br.com.alura.modelo.loja.Produto;
import util.JPAUtil;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class CadastroDeProduto {
     public static void main(String[] args) {
          Categoria celulares = new Categoria("celulares");

          //criando um objeto e setando as informações dele  --- da linha 12 até a 15 eu estou simulando um usuario
          Produto celular = new Produto("Iphone 15","129 gb", celulares);


        // a loja_virtual  peguei do persistence unit
        //  EntityManagerFactory factory = Persistence.createEntityManagerFactory("loja_virtual");
         // EntityManager em = factory.createEntityManager();

          EntityManager em = JPAUtil.getEntityManager();
          ProdutoDAO produtoDao = new ProdutoDAO(em);
          CategoriaDAO categoriaDAO = new CategoriaDAO(em);

          em.getTransaction().begin();

         // em.persist(celular);  vai deixar de ser essa linha para ser a de baixo
          categoriaDAO.cadastrar(celulares);// salvei a categoria primeiro e depois o produtos
          produtoDao.cadastrar(celular);

          em.getTransaction().commit();
          em.close();
     }

}

E a Exception

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Qual exception? manda aqui a stack trace

Você não está utilizando o banco H2, certo?

Sugestão é você apagar e criar novamente o banco de dados então, pois pode estar dando problema por conta da estrutura anterior.

ERROR: Cannot add or update a child row: a foreign key constraint fails (`loja_virtual`.`produto`, CONSTRAINT `produto_ibfk_1` FOREIGN KEY (`categoria_id`) REFERENCES `categoria` (`id`))
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:726)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:706)
    at br.com.alura.dao.ProdutoDAO.cadastrar(ProdutoDAO.java:15)
    at br.com.alura.modelo.teste.CadastroDeProduto.main(CadastroDeProduto.java:33)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
    at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3200)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3806)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:720)
    ... 3 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`loja_virtual`.`produto`, CONSTRAINT `produto_ibfk_1` FOREIGN KEY (`categoria_id`) REFERENCES `categoria` (`id`))
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
    ... 21 more

Process finished with exit code 1

Nesse caso se eu der um drop nas, só pelo que fizemos em aula eu consigo criar novamente, ou preciso fazer tudo da criação do banco?

solução!

Pode dar unm drop nas 2 tabelas, que o Hibernate vai criar novamente quando rodar a classe main

Dessa forma funcionou, obrigado!