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

Problemas com o mapeamento das classes no JPA

Bom dia pessoal!

Eu normalizei as tabelas do sistema, porém ao fazer isso tudo parou de funcionar... Minha estrutura está dessa forma:

Classe Produto:

package br.com.minhaEmpresa.modelo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.validator.constraints.NotEmpty;

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

    // ATRIBUTOS "COMUNS" PARA TODOS OS PRODUTOS:
    @Id
    @Column(length = 10)
    @GeneratedValue(strategy = GenerationType.IDENTITY) // MYSQL
    private Integer id;

    @NotEmpty
    @Column(name = "codigo_produto", length = 24)
    private String codigoProduto;

    @Column(columnDefinition = "Character(1)")
    private Character catalogo;

    @Column(name = "descricao_tipo_produto", length = 30)
    private String descricaoTipoProduto;

    @Column(length = 19)
    private Integer ean;

    @Column(length = 30)
    private String imagem;

    @Column(name = "imagem_embalagem", length = 40)
    private String imagemEmbalagem;

    @Column(columnDefinition = "Character(1)")
    private Character lancamento;

    @Column(columnDefinition = "Character(1)")
    private Character liberado;

    @Column(name = "local_imagem", length = 200)
    private String localImagem;

    @Column(length = 30)
    private String marca;

    @Column(length = 19)
    private Integer ncm;

    @Column(columnDefinition = "Character(1)")
    private Character original;

    @Column
    private Double peso;

    @Column
    private Double preco;

    @Column(columnDefinition = "Character(1)")
    private Character promocao;

    @Column(name = "queima_estoque", columnDefinition = "Character(1)")
    private Character queimaEstoque;

    @Column(length = 60)
    private String semelhantes;

    @Column(name = "tipo_produto")
    private Integer tipoProduto;

    /******************************************************************************/
    // MAPEAMENTO
    @OneToOne
    private ProdutoEco produtoEco;

    @OneToOne
    private ProdutoVaz produtoVaz;

    @OneToOne
    private ProdutoVazCap produtoVazCap;

    /******************************************************************************/

    public Integer getId() {
        return id;
    }

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

    public String getCodigoProduto() {
        return codigoProduto;
    }

    public void setCodigoProduto(String codigoProduto) {
        this.codigoProduto = codigoProduto;
    }

    public Character getCatalogo() {
        return catalogo;
    }

    public void setCatalogo(Character catalogo) {
        this.catalogo = catalogo;
    }

    public String getDescricaoTipoProduto() {
        return descricaoTipoProduto;
    }

    public void setDescricaoTipoProduto(String descricaoTipoProduto) {
        this.descricaoTipoProduto = descricaoTipoProduto;
    }

    public Integer getEan() {
        return ean;
    }

    public void setEan(Integer ean) {
        this.ean = ean;
    }

    public String getImagem() {
        return imagem;
    }

    public void setImagem(String imagem) {
        this.imagem = imagem;
    }

    public String getImagemEmbalagem() {
        return imagemEmbalagem;
    }

    public void setImagemEmbalagem(String imagemEmbalagem) {
        this.imagemEmbalagem = imagemEmbalagem;
    }

    public Character getLancamento() {
        return lancamento;
    }

    public void setLancamento(Character lancamento) {
        this.lancamento = lancamento;
    }

    public Character getLiberado() {
        return liberado;
    }

    public void setLiberado(Character liberado) {
        this.liberado = liberado;
    }

    public String getLocalImagem() {
        return localImagem;
    }

    public void setLocalImagem(String localImagem) {
        this.localImagem = localImagem;
    }

    public String getMarca() {
        return marca;
    }

    public void setMarca(String marca) {
        this.marca = marca;
    }

    public Integer getNcm() {
        return ncm;
    }

    public void setNcm(Integer ncm) {
        this.ncm = ncm;
    }

    public Character getOriginal() {
        return original;
    }

    public void setOriginal(Character original) {
        this.original = original;
    }

    public Double getPeso() {
        return peso;
    }

    public void setPeso(Double peso) {
        this.peso = peso;
    }

    public Double getPreco() {
        return preco;
    }

    public void setPreco(Double preco) {
        this.preco = preco;
    }

    public Character getPromocao() {
        return promocao;
    }

    public void setPromocao(Character promocao) {
        this.promocao = promocao;
    }

    public Character getQueimaEstoque() {
        return queimaEstoque;
    }

    public void setQueimaEstoque(Character queimaEstoque) {
        this.queimaEstoque = queimaEstoque;
    }

    public String getSemelhantes() {
        return semelhantes;
    }

    public void setSemelhantes(String semelhantes) {
        this.semelhantes = semelhantes;
    }

    public Integer getTipoProduto() {
        return tipoProduto;
    }

    public void setTipoProduto(Integer tipoProduto) {
        this.tipoProduto = tipoProduto;
    }

    public ProdutoEco getProdutoEco() {
        return produtoEco;
    }

    public void setProdutoEco(ProdutoEco produtoEco) {
        this.produtoEco = produtoEco;
    }

    public ProdutoVaz getProdutoVaz() {
        return produtoVaz;
    }

    public void setProdutoVaz(ProdutoVaz produtoVaz) {
        this.produtoVaz = produtoVaz;
    }

    public ProdutoVazCap getProdutoVazCap() {
        return produtoVazCap;
    }

    public void setProdutoVazCap(ProdutoVazCap produtoVazCap) {
        this.produtoVazCap = produtoVazCap;
    }
}

Classe ProdutoVaz, que seria no caso os detalhes do produto:

package br.com.minhaEmpresa.modelo;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name = "TAB_PROD_VAZ_DT")
public class ProdutoVaz {

    @Id
    @Column(length = 19)
    @GeneratedValue(strategy = GenerationType.IDENTITY) // MYSQL
    private Integer id;

    @NotEmpty
    @Column(name = "codigo_produto", length = 24)
    private String codigoProduto;

    @Column(name = "ate_ano", length = 10)
    private String ateAno;

    @Column
    private Integer cilindrada;

    @Column(name = "de_ano", length = 4)
    private String deAno;

    @Column(name = "dianteira_traseira", length = 3)
    private String dianteiraTraseira;

    @Column(length = 80)
    private String modelo;

    @Column(length = 30)
    private String montadora;

    @Column(name = "nro_dentes_elos", length = 10)
    private Integer nroDentesElos;

    @Column(name = "pinca_dupla", columnDefinition = "Character(1)")
    private Character pincaDupla;

    @Column(name = "sulfixo_opcional", length = 6)
    private String sulfixoOpcional;

    /******************************************************************************/
  //  MAPEAMENTO:
    @OneToOne(mappedBy = "produtoVaz")
    private Produto produto;

    @OneToMany
    @JoinColumn(name = "produtoVazKit_id")
    private List<ProdutoVazKit> produtoVazKits;

    @OneToMany
    @JoinColumn(name = "produtoVazPrefixo_id")
    private List<ProdutoVazPrefixo> produtoVazPrefixos;

    /******************************************************************************/

    public Integer getId() {
        return id;
    }

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

    public String getCodigoProduto() {
        return codigoProduto;
    }

    public void setCodigoProduto(String codigoProduto) {
        this.codigoProduto = codigoProduto;
    }

    public String getAteAno() {
        return ateAno;
    }

    public void setAteAno(String ateAno) {
        this.ateAno = ateAno;
    }

    public Integer getCilindrada() {
        return cilindrada;
    }

    public void setCilindrada(Integer cilindrada) {
        this.cilindrada = cilindrada;
    }

    public String getDeAno() {
        return deAno;
    }

    public void setDeAno(String deAno) {
        this.deAno = deAno;
    }

    public String getDianteiraTraseira() {
        return dianteiraTraseira;
    }

    public void setDianteiraTraseira(String dianteiraTraseira) {
        this.dianteiraTraseira = dianteiraTraseira;
    }

    public String getModelo() {
        return modelo;
    }

    public void setModelo(String modelo) {
        this.modelo = modelo;
    }

    public String getMontadora() {
        return montadora;
    }

    public void setMontadora(String montadora) {
        this.montadora = montadora;
    }

    public Integer getNroDentesElos() {
        return nroDentesElos;
    }

    public void setNroDentesElos(Integer nroDentesElos) {
        this.nroDentesElos = nroDentesElos;
    }

    public Character getPincaDupla() {
        return pincaDupla;
    }

    public void setPincaDupla(Character pincaDupla) {
        this.pincaDupla = pincaDupla;
    }

    public String getSulfixoOpcional() {
        return sulfixoOpcional;
    }

    public void setSulfixoOpcional(String sulfixoOpcional) {
        this.sulfixoOpcional = sulfixoOpcional;
    }

    public Produto getProduto() {
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public List<ProdutoVazKit> getProdutoVazKits() {
        return produtoVazKits;
    }

    public void setProdutoVazKits(List<ProdutoVazKit> produtoVazKits) {
        this.produtoVazKits = produtoVazKits;
    }

    public List<ProdutoVazPrefixo> getProdutoVazPrefixos() {
        return produtoVazPrefixos;
    }

    public void setProdutoVazPrefixos(List<ProdutoVazPrefixo> produtoVazPrefixos) {
        this.produtoVazPrefixos = produtoVazPrefixos;
    }
}

Meu ProdutoDao:

package br.com.minhaEmpresa.dao;

import java.util.List;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import br.com.caelum.vraptor.Result;
import br.com.minhaEmpresa.modelo.Montadora;
import br.com.minhaEmpresa.modelo.Produto;
import br.com.minhaEmpresa.modelo.TipoProduto;

@RequestScoped
public class ProdutoDao {

    private EntityManager manager;

    @Inject
    public ProdutoDao(EntityManager manager) {
        this.manager = manager;
    }

    // PARA USO DO CDI
    public ProdutoDao() {
    }

    public void salva(Produto produto) {
        manager.getTransaction().begin();
        if (produto.getId() == null) {
            manager.persist(produto);
        } else {
            manager.merge(produto);
        }
        manager.getTransaction().commit();
        manager.close();
    }

    /*****************************************************************************************************/
    public Produto atualizaProdutoVaz(Integer id, Result result) {
        Produto produto = this.buscaProdutoVaz(id);
        return produto;
    }

    public Produto atualizaProdutoEco(Integer id, Result result) {
        Produto produto = this.buscaProdutoEco(id);
        return produto;
    }

    public Produto atualizaProdutoVazCap(Integer id, Result result) {
        Produto produto = this.buscaProdutoVazCap(id);
        return produto;
    }

    /*****************************************************************************************************/
    public Produto buscaProdutoVaz(Integer id) {
        try {
            TypedQuery<Produto> query = manager.createQuery("Select pvaz.codigoProduto, p.descricaoTipoProduto, "
                    + "pvaz.sulfixoOpcional, pvaz.montadora, pvaz.modelo, pvaz.deAno, pvaz.ateAno, "
                    + "pvaz.cilindrada, pvaz.nroDentesElos, pvaz.dianteiraTraseira, pvaz.pincaDupla, "
                    + "p.marca, p.original, p.liberado, p.lancamento, p.promocao, p.queimaEstoque, "
                    + "p.preco, p.semelhantes, p.imagemEmbalagem, p.imagem, p.localImagem, p.peso, "
                    + "p.ean, p.ncm, p.catalogo "
                    + "From Produto p left join ProdutoVaz pvaz on p.codigoProduto = pvaz.codigoProduto "
                    + "Where p.id = :id", Produto.class);
            query.setParameter("id", id);
            return query.getSingleResult();
        } catch (Exception e) {
            return null;
        }
    }

    public Produto buscaProdutoEco(Integer id) {
        try {
            TypedQuery<Produto> query = manager.createQuery("Select peco.codigoProduto, p.descricaoTipoProduto, "
                    + "peco.montadora, peco.modelo, peco.deAno, peco.ateAno, peco.linhaVeiculo, "
                    + "peco.sistemaFreio, peco.dianteiraTraseira, p.marca, p.original, p.liberado, "
                    + "p.lancamento, p.promocao, p.queimaEstoque, p.preco, p.semelhantes, p.imagemEmbalagem, "
                    + "p.imagem, p.localImagem, peco.comprimento, peco.largura, peco.espessura, p.catalogo "
                    + "From Produto p join ProdutoEco peco on p.codigoProduto = peco.codigoProduto "
                    + "Where p.id = :id", Produto.class);
            query.setParameter("id", id);
            return query.getSingleResult();
        } catch (Exception e) {
            return null;
        }
    }

    public Produto buscaProdutoVazCap(Integer id) {
        try {
            TypedQuery<Produto> query = manager.createQuery("Select pvazcap.codigoProduto, p.descricaoTipoProduto, "
                    + "pvazcap.codigoRapido, p.marca, pvazcap.modeloTipoProduto, pvazcap.descricao, pvazcap.modelo, "
                    + "pvazcap.tamanho, pvazcap.cor, pvazcap.decal, pvazcap.corDecal, pvazcap.adesivo, "
                    + "pvazcap.corAdesivo, p.original, p.liberado, p.lancamento, p.promocao, p.queimaEstoque, "
                    + "p.preco, p.semelhantes, p.imagemEmbalagem, p.imagem, p.localImagem, p.catalogo "
                    + "From Produto p join ProdutoVazVap pvazcap on p.codigoProduto = pvazcap.codigoProduto "
                    + "Where p.id = :id", Produto.class);
            query.setParameter("id", id);
            return query.getSingleResult();
        } catch (Exception e) {
            return null;
        }
    }

    /*****************************************************************************************************/
    public TipoProduto buscaTPPorDescricao(String descricaoTipoProduto) {
        try {
            TypedQuery<TipoProduto> query = manager.createQuery(
                    "Select tp From TipoProduto tp where tp.descricaoTipoProduto = :descricaoTipoProduto",
                    TipoProduto.class);
            query.setParameter("descricaoTipoProduto", descricaoTipoProduto);
            return query.getSingleResult();
        } catch (Exception e) {
            return null;
        }
    }

    public List<TipoProduto> listaTipoProduto(String marca) {
        try {
            TypedQuery<TipoProduto> query = manager.createQuery(
                    "Select tp  From TipoProduto tp Where tp.marca = :marca Order By tp.descricaoTipoProduto",
                    TipoProduto.class);
            query.setParameter("marca", marca);
            return query.getResultList();
        } catch (Exception e) {
            return null;
        }
    }

    /*****************************************************************************************************/
    public List<Produto> listaVaz(String marca1, String marca2) {
        try {
            TypedQuery<Produto> query = manager
                    .createQuery("Select p.codigoProduto, p.tipoProduto, p.descricaoTipoProduto, pvaz.montadora, "
                            + "pvaz.modelo, pvaz.deAno, pvaz.ateAno, pvaz.cilindrada, pvazprefixo.tipoCorrente, "
                            + "pvaz.nroDentesElos, pvaz.dianteiraTraseira, p.original, p.promocao, p.queimaEstoque, "
                            + "p.preco, p.imagem, p.peso "
                            + "From Produto p join ProdutoVaz pvaz on p.codigoProduto = pvaz.codigoProduto "
                            + "join ProdutoVazPrefixo pvazprefixo on pvaz.codigoProduto = pvazprefixo.codigoProduto "
                            + "and p.marca = :marca1 or p.marca = :marca2 ", Produto.class);
            query.setParameter("marca1", marca1);
            query.setParameter("marca2", marca2);

            if (query.getResultList().isEmpty()) {
                System.out.println("ProdutoDao: A query está VAZIA...");
            } else {
                System.out.println("ProdutoDao: A query NÃO está VAZIA...");
            }
            List<Produto> resultado = query.getResultList();
            return resultado;
        } catch (Exception e) {
            return null;
        }
    }

    public List<Produto> listaEco(String marca) {
        try {
            TypedQuery<Produto> query = manager.createQuery(
                    "Select peco.codigoProduto, peco.montadora, peco.modelo, peco.deAno, peco.ateAno, "
                            + "peco.linhaVeiculo, peco.sistemaFreio, peco.dianteiraTraseira, p.original,  "
                            + "p.preco, p.semelhantes, peco.comprimento, peco.largura, peco.espessura "
                            + "From Produto p join ProdutoEco peco on p.codigoProduto = peco.codigoProduto ",
                    Produto.class);
            query.setParameter("marca", marca);
            return query.getResultList();
        } catch (Exception e) {
            return null;
        }
    }

    public List<Produto> listaVazCap(String marca) {
        try {
            TypedQuery<Produto> query = manager.createQuery(
                    "Select pvazcap.codigoProduto, pvazcap.tipoProduto, pvazcap.descricaoTipoProduto, "
                            + "pvazcap.codigoRapido, pvazcap.descricao, pvazcap.modelo, pvazcap.tamanho, "
                            + "pvazcap.cor, pvazcap.decal, pvazcap.corDecal, pvazcap.adesivo, "
                            + "pvazcap.corAdesivo, p.preco, p.semelhantes "
                            + "From Produto p join ProdutoVazCap pvazcap on p.codigoProduto = pvazcap.codigoProduto ",
                    Produto.class);
            query.setParameter("marca", marca);
            return query.getResultList();
        } catch (Exception e) {
            return null;
        }
    }

    /*********************************************************************************************************************/

    public List<Montadora> listaMontadora(String marca) {
        try {
            TypedQuery<Montadora> query = manager
                    .createQuery("Select m From Montadora m Where m.marca = :marca Order By m.nome", Montadora.class);
            query.setParameter("marca", marca);
            return query.getResultList();
        } catch (Exception e) {
            return null;
        }
    }
}

ProdutoController:

package br.com.minhaEmpresa.controller;

import java.io.File;
import java.util.List;

import javax.inject.Inject;
import javax.validation.Valid;

import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.interceptor.IncludeParameters;
import br.com.caelum.vraptor.validator.Validator;
import br.com.minhaEmpresa.dao.ProdutoDao;
import br.com.minhaEmpresa.modelo.Montadora;
import br.com.minhaEmpresa.modelo.Produto;
import br.com.minhaEmpresa.modelo.TipoProduto;

@Controller
public class ProdutoController {

    private ProdutoDao produtoDao;
    private Result result;
    private Validator validator;

    @Inject
    public ProdutoController(ProdutoDao produtoDao, Result result, Validator validator) {
        this.produtoDao = produtoDao;
        this.result = result;
        this.validator = validator;
    }

    // PARA USO DO CDI
    public ProdutoController() {
    }

    public void formVaz() {
        listaTipoProduto("VAZ");
        listaMontadora("VAZ");
    }

    public void formEco() {
        listaTipoProduto("ECOPADS");
        listaMontadora("ECOPADS");
    }

    public void formVazCap() {
        listaTipoProduto("VAZCAP");
        listaMontadora("VAZCAP");
    }

    /*****************************************************************************************/
    // MÉTODO SALVA:

    @IncludeParameters
    public void salvaVaz(@Valid Produto produto, TipoProduto tipoProduto) {
        validator.onErrorRedirectTo(this).formVaz();
        tipoProduto = produtoDao.buscaTPPorDescricao(produto.getDescricaoTipoProduto());
        produto.setTipoProduto(tipoProduto.getTipoProduto());
        produtoDao.salva(produto);
        result.redirectTo(this).listaVaz();
    }

    @IncludeParameters
    public void salvaEco(@Valid Produto produto, TipoProduto tipoProduto) {
        validator.onErrorRedirectTo(this).formEco();
        tipoProduto = produtoDao.buscaTPPorDescricao(produto.getDescricaoTipoProduto());
        produto.setTipoProduto(tipoProduto.getTipoProduto());
        produtoDao.salva(produto);
        result.redirectTo(this).listaEco();
    }

    @IncludeParameters
    public void salvaVazCap(@Valid Produto produto, TipoProduto tipoProduto) {
        validator.onErrorRedirectTo(this).formVazCap();
        produtoDao.salva(produto);
        result.redirectTo(this).listaVazCap();
    }

    /*****************************************************************************************/
    // MÉTODO ATUALIZA:

    public void atualizaVaz(Integer id, Result result) {
        Produto produto = produtoDao.buscaProdutoVaz(id);
        result.include(produto);
        listaTipoProduto("VAZ");
        listaMontadora("VAZ");
        imgProdutoVaz(id);
        result.of(this).formVaz();
    }

    public void atualizaEco(Integer id, Result result) {
        Produto produto = produtoDao.buscaProdutoEco(id);
        result.include(produto);
        listaTipoProduto("ECOPADS");
        listaMontadora("ECOPADS");
        imgProdutoEco(id);
        result.of(this).formEco();
    }

    public void atualizaVazCap(Integer id, Result result) {
        Produto produto = produtoDao.buscaProdutoVazCap(id);
        result.include(produto);
        listaTipoProduto("VAZCAP");
        listaMontadora("VAZCAP");
        imgProdutoVazCap(id);
        result.of(this).formVazCap();
    }

    /*****************************************************************************************/
    // MÉTODOS PARA CARREGAR IMAGEM DO PRODUTO NO FORM:

    @Get("produto/{id}/imgProdutoVaz")
    public File imgProdutoVaz(Integer id) {
        Produto produto = produtoDao.buscaProdutoVaz(id);

        // CAMINHO PARA CARREGAR A IMAGEM DURANTE O DESENVOLVIMENTO:
        String caminho = produto.getLocalImagem() + "\\" + produto.getImagem();

        // CAMINHO PARA CARREGAR A IMAGEM NO SERVIDOR LINUX:
        // String caminho = produto.getLocalImagem().toString().replace("F:",
        // "/mnt/fileserver/minhaEmpresa") + "/" + produto.getImagem();

        caminho = caminho.replace("\\", "/");

        if (!caminho.contains("jpg")) {
            return null;
        } else {
            File arquivo = new File(caminho);
            return arquivo;
        }
    }

    @Get("produto/{id}/imgProdutoEco")
    public File imgProdutoEco(Integer id) {
        Produto produto = produtoDao.buscaProdutoEco(id);

        // CAMINHO PARA CARREGAR A IMAGEM DURANTE O DESENVOLVIMENTO:
        String caminho = produto.getLocalImagem() + "\\" + produto.getImagem();

        // CAMINHO PARA CARREGAR A IMAGEM NO SERVIDOR LINUX:
        // String caminho = produto.getLocalImagem().toString().replace("F:",
        // "/mnt/fileserver/minhaEmpresa") + "/" + produto.getImagem();

        caminho = caminho.replace("\\", "/");

        if (!caminho.contains("jpg")) {
            return null;
        } else {
            File arquivo = new File(caminho);
            return arquivo;
        }
    }

    @Get("produto/{id}/imgProdutoVazCap")
    public File imgProdutoVazCap(Integer id) {
        Produto produto = produtoDao.buscaProdutoVaz(id);

        // CAMINHO PARA CARREGAR A IMAGEM DURANTE O DESENVOLVIMENTO:
        String caminho = produto.getLocalImagem() + "\\" + produto.getImagem();

        // CAMINHO PARA CARREGAR A IMAGEM NO SERVIDOR LINUX:
        // String caminho = produto.getLocalImagem().toString().replace("F:",
        // "/mnt/fileserver/minhaEmpresa") + "/" + produto.getImagem();

        caminho = caminho.replace("\\", "/");

        if (!caminho.contains("jpg")) {
            return null;
        } else {
            File arquivo = new File(caminho);
            return arquivo;
        }
    }

    /*****************************************************************************************/
    // MÉTODO LISTA DE PRODUTOS DE CADA EMPRESA

    public void listaVaz() {
        List<Produto> produtos = produtoDao.listaVaz("VAZ", "XTREME");
        if(produtos  == null){
            System.out.println("ProdutoController: A List produtos está NULA...");
        } else{
            System.out.println("ProdutoController: A List produtos NÃO está NULA...");
        }
        result.include("produtos", produtos);
    }

    public void listaEco() {
        List<Produto> produtos = produtoDao.listaEco("ECOPADS");
        result.include("produtos", produtos);
    }

    public void listaVazCap() {
        List<Produto> produtos = produtoDao.listaVazCap("VAZCAP");
        result.include("produtos", produtos);
    }

    /*****************************************************************************************/

    public void listaMontadora(String marca) {
        List<Montadora> montadoras = produtoDao.listaMontadora(marca);
        result.include("montadoras", montadoras);
    }

    public void listaTipoProduto(String marca) {
        List<TipoProduto> tiposProduto = produtoDao.listaTipoProduto(marca);
        result.include("tiposProduto", tiposProduto);
    }
}
20 respostas

Ao tentar salvar um registro, gera o erro:

HTTP Status 500 - Error while committing the transaction

type Exception report

message Error while committing the transaction

description The server encountered an internal error that prevented it from fulfilling this request.

exception

Stack no console:

GRAVE: Servlet.service() for servlet [default] in context with path [/ebf-catalogo-mysql] threw exception
javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:87)
    at br.com.ebf.dao.ProdutoDao.salva(ProdutoDao.java:36)
    at br.com.ebf.dao.ProdutoDao$Proxy$_$$_WeldClientProxy.salva(Unknown Source)
    at br.com.ebf.controller.ProdutoController.salvaVaz(ProdutoController.java:60)


Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : br.com.ebf.modelo.Produto.produtoVaz -> br.com.ebf.modelo.ProdutoVaz
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1689)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
    at org.hibernate.jpa.internal.EntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3139)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2352)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:491)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
    ... 82 more
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : br.com.ebf.modelo.Produto.produtoVaz -> br.com.ebf.modelo.ProdutoVaz
    at org.hibernate.engine.spi.CascadingActions$8.noCascade(CascadingActions.java:379)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:119)
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:150)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:141)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:74)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:468)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3135)

Oi Ewerton,

O que está acontecendo é que você está tentando salvar um Produto que está vinculado a um ProdutoVaz que não foi salvo ainda ou não foi recuperado do BD antes de ser vinculado ao Produto.

Se o ProdutoVaz existir, você só precisará buscá-lo no BD para que ele fique no estado Managed e não Transient.

Se o ProdutoVaz não existir, você pode persisti-lo antes de persistir o Produto ou deixar que o Hibernate faça a persistência para você utilizando a opção cascade na anotação que faz o mapeamento do ProdutoVaz dentro da classe Produto.

Abraço!

Oi Ewerton, primeiramente, no teu mapeamento, eu não consegui identificar quem é o lado forte e quem é o lado fraco da associação,como você escolheu mapear de forma bidirecional, um dos lados tem que ser o lado forte e o outro lado deve ser o lado fraco(deve conter o @JoinColumn).

O segundo ponto(provavelmente referente a exception) é que quando você tem relacionamentos bidirecionais, você deve preencher os dois lados do relacionamento(produto deve conhecer produtoVaz e produtoVaz deve conhecer o seu produto), no caso do seu mapeamento você não escolheu nenhuma operação de cascade, então vc faria algo do tipo:

produto = salvarProduto(produto); produto.setProdutoVaz(produtoVaz); produtoVaz.setProduto(produto); salvarProdutoVaz(produtoVaz) updateProduto(produto)

se vc habilitar operações em cascata fica mais fácil ainda //ainda assim deve preencher os dois lados do //relacionamento produto.setProdutoVaz(produtoVaz); produtoVaz.setProduto(produto); salvarProduto(produto);//salva o produto vaz por tabela

outro ponto é que relacinamentos OneToOne são eager por padrão, vc não precisa de um join para carregar o produtoVaz, quando vc recuperar um produto com a JPQL, o produtoVaz já vem carragado

dá uma olhada nesse guia, é bem bacana:http://uaihebert.com/jpa-onetoone-unidirecional-e-bidirecional/

Alterei os mapeamentos:

Produto:

    @OneToOne(cascade = CascadeType.PERSIST)
    private ProdutoEco produtoEco;

    @OneToOne(cascade = CascadeType.PERSIST)
    private ProdutoVaz produtoVaz;

    @OneToOne(cascade = CascadeType.PERSIST)
    private ProdutoVazCap produtoVazCap;

ProdutoVaz:

    @OneToOne(mappedBy = "produtoVaz")
    private Produto produto;

    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "produtoVaz")
    private List<ProdutoVazKit> produtoVazKits;

    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "produtoVaz")
    private List<ProdutoVazPrefixo> produtoVazPrefixos;

Porém ao salvar, gera o erro no browser:

HTTP Status 500 - Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]

type Exception report

message Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.validation.ConstraintViolationException: Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Não pode estar vazio', propertyPath=codigoProduto, rootBeanClass=class br.com.ebf.modelo.ProdutoVaz, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
]

E no console do Eclipse:

mar 13, 2017 4:31:03 PM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [default] in context with path [/ebf-catalogo-mysql] threw exception
javax.validation.ConstraintViolationException: Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Não pode estar vazio', propertyPath=codigoProduto, rootBeanClass=class br.com.ebf.modelo.ProdutoVaz, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
]

olha na tua Classe produto

@NotEmpty
    @Column(name = "codigo_produto", length = 24)
    private String codigoProduto;

você está utilizando bean validation na classe Produto. Com a anotação @NotEmpty voê está informando para a JPA que o campo codigoProduto é obrigatorio, não pode ser nulo e nem pode ser uma String vazia. A exception tá dizendo que vc tentou salvar uma entidade se esse código produto

Mais uma observação, em relacionamentos bidirecionais eu costumo ussar cascade apenas no lado forte do relacionamento, veja bem, faz sentido que quando um produto for removido seus detalhes sejam removidos, mas não faz sentido algum quando eu remover um detalhe de um produto que o produto seja removido

Bom dia Ricardo!

Alterei o mapeamento, minha classe Produto (LADO DOMINANTE):

@OneToOne(cascade = CascadeType.PERSIST)
private ProdutoVaz produtoVaz;

Eu achei que a anotação @JoinColumn só era utilizada para @OneToMany, então fiz conforme vc me orientou na ProdutoVaz:

@OneToOne(mappedBy = "produtoVaz")
@JoinColumn(name = "produto_id")
private Produto produto;

Mantive meu ProdutoDao como estava:

    public void salva(Produto produto) {
        manager.getTransaction().begin();
        if (produto.getId() == null) {
            manager.persist(produto);
        } else {
            manager.merge(produto);
        }
        manager.getTransaction().commit();
        manager.close();
    }

E na ProdutoController, alterei para :

@IncludeParameters
public void salvaVaz(@Valid Produto produto, ProdutoVaz produtoVaz, TipoProduto tipoProduto) {
        validator.onErrorRedirectTo(this).formVaz();
        tipoProduto = produtoDao.buscaTPPorDescricao(produto.getDescricaoTipoProduto());
        produto.setTipoProduto(tipoProduto.getTipoProduto());

        // Linhas adicionadas
        produto.setProdutoVaz(produtoVaz);
        produtoVaz.setProduto(produto);

        produtoDao.salva(produto);
        result.redirectTo(this).listaVaz();
    }

Porém ao tentar salvar um registro recebo o erro no browser:

HTTP Status 500 - Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]

type Exception report

message Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.validation.ConstraintViolationException: Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Não pode estar vazio', propertyPath=codigoProduto, rootBeanClass=class br.com.ebf.modelo.ProdutoVaz, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
]

E a stack no console do Eclipse:

mar 14, 2017 9:42:09 AM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [default] in context with path [/ebf-catalogo-mysql] threw exception
javax.validation.ConstraintViolationException: Validation failed for classes [br.com.ebf.modelo.ProdutoVaz] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Não pode estar vazio', propertyPath=codigoProduto, rootBeanClass=class br.com.ebf.modelo.ProdutoVaz, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
]

O Hibernate está reclamando que codigoProduto na classe ProdutoVaz está Nula, mas no ProdutoController eu não estou passando...?

Obrigado pela ajuda!!

dá u print no código bem aqui nessa parte do teu código e vê oque ele imprime:

public void salva(Produto produto) {
        manager.getTransaction().begin();

System.out.println("código: "+produto.getCodigo());
        if (produto.getId() == null) {
            manager.persist(produto);
        } else {
            manager.merge(produto);
        }
        manager.getTransaction().commit();
        manager.close();
    }

Adicionei um print no ProdutoDao, e imprimiu corretamente o código que eu informei no form...

    public void salva(Produto produto) {
        manager.getTransaction().begin();
        System.out.println("EVD - cógio: " + produto.getCodigoProduto());
        if (produto.getId() == null) {
//restante do código...

Adicionei dois prints no ProdutoController, imprimiu o codigoProduto do PRODUTO, mas o codigoProduto do PRODUTOVAZ não foi inpresso, recebi null...

    // MÉTODO SALVA:

    @IncludeParameters
    public void salvaVaz(@Valid Produto produto, ProdutoVaz produtoVaz, TipoProduto tipoProduto) {
        validator.onErrorRedirectTo(this).formVaz();
        tipoProduto = produtoDao.buscaTPPorDescricao(produto.getDescricaoTipoProduto());
        produto.setTipoProduto(tipoProduto.getTipoProduto());

        // Linhas adicionadas
        produtoVaz.setProduto(produto);
        produto.setProdutoVaz(produtoVaz);

        System.out.println("Código Produto no CONTROLLER: " + produto.getCodigoProduto());
        System.out.println("Código ProdutoVaz no CONTROLLER: " + produtoVaz.getCodigoProduto());

        produtoDao.salva(produto);
        result.redirectTo(this).listaVaz();
    }

E é justamente o codigoProduto do ProdutoVaz, que o Hibernate está reclamando, na stack...

isso é bom, pelo menos agora vc já sabe que o problema não é mais no mapeamento e sim no preenchimento do objeto, faz o seguinte teste apenas pra ver se realmente tá salvando

 // Linhas adicionadas
        produto.setProdutoVaz(produtoVaz);
produtoVaz.setCodigo(produto.getCodigo()); //seta algum código manualmente
        produtoVaz.setProduto(produto);

        System.out.println("EVD - cógio no CONTROLLER: " + produtoVaz.getCodigoProduto());

//Restante do código...
//Salvar produto...

Tem que ver agora como vc esta passando esse código do produto vaz para o controller, com o vraptor lá na jsp vc deve ter algo parecido como:

<input type="text" name="produto.produtoVaz.codigo"/>

ou dependendo de como vc estiver implementando

<input type="text" name="produtoVaz.codigo"/>

o importante é que os names dos inputs batam com o nome dos atributos dos objetos

Setei o codigoProduto do ProdutoVaz na mão e salvou o registro no BD... Beleza!

Agora quanto a questão do input no jsp...tenho apenas "um" input, pro codigoProduto do Produto...

<input type="text" name="produto.codigoProduto" id="codigoProduto" value="${produto.codigoProduto}" />

Deixei de setar o codigoProduto do ProdutoVaz, na mão... E adicionei um input do tipo "hidden" para ele no formulário, mas ai o erro voltou a ocorrer...

alguns questionamentos: 1- O código do produtoDev é igual ao código do produto? 2 - O código do produtoDev é informado pelo usuário? 3-Como vc está recebendo estes objetos no controlador?

solução!

pelo que vi no código que vc postou anteriormente, vc está recebendo os objetos assim:

public void salvaVaz(@Valid Produto produto, ProdutoVaz produtoVaz, TipoProduto tipoProduto){}

esse produto vaz tem que vir preenchido de algum lugar

se for o usuario que deve informar este produtoVaz, você tem que definir um input para o usuario digitar este código

<input type="text" name="produtoVaz.codico" value="$produtoVaz.codigo" />

se esse código for igual ao código do produto ou se vc pega esse código de outro local, vc pode setar ele manualmente no proprio controlador ou no seu dAO mesmo

Bom dia Ricardo!

Perfeito cara, muito obrigado ajuda!! Obrigado também Joviane!!

Só mais uma pergunta na minha listagem tenho 15 colunas...

Não fica mais lento se eu fizer na TypedQuery:

Select p From Produto p Where...

Do que se eu fizesse:

Select p.campo1,..., p.campo15
From Produto p
Where...

No primeiro select eu não carrego todos os campos das tabelas relacionadas no cache ??

Obrigado e um abraço!!

.....

Oi Ewerton, que bom que deu certo! Sim você fazer

Select p From Produto p Where...

é mais lento que você fazer

Select p.campo1,..., p.campo15
From Produto p
Where...

entretanto essa segunda consulta não vai te retornar uma lista de produtos, mas sim uma lista de arrays:

List<Produto> produtos = new ArrayList<Produto>();
Query<Produto> q = manager.createQuery("select p.campo1, p.campo2,p.campo15 from Produto p where ...");

List<Object[]> results =  q.getResulList();

for(Object[] o : results){
Produto p = new Produto();
//a posição é a posição que o campo aparece na query
p.setCampo1((Cast) o[0]);
p.setCampo2((Cast) o[1]);
p.setCampo15((Cast) o[2]);
}
return produtos;

Se forem poucos campos que vc quer recuperar, uma alternativa melhor é fazer a querie através de construtores

public class Produto(){
//resto do codigo

public Produto(String campo1, String campo2,Integer campo3){
 this.campo1 = campo1;
this.campo2 = campo2;
this.campo15 = campo15;
}
}

e na query

TypedQuery<Produto> q  = manager.createQuery("select new  br.com.nomedopacote.Produto(p.campo1, p.campo2, p.campo15) from Produto p where ... ",Produto.class);

return q.getResultList();

Deu um problema ao tentar salvar um registro Ricardo... Abri um novo post => https://cursos.alura.com.br/forum/topico-erro-ao-tentar-salvar-um-registro-com-tabelas-relacionadas-34400

Agradeço se vc puder dar uma olhada, fica mais fácil pq vc já conhece a estrutura... Obrigado!!!