Erro em mapeamento @OneToMany e @ManyToOne

11 respostas
N

Pessoal,

Estou com o seguinte erro na minha aplicação "Use of @OneToMany or @ManyToMany targeting an unmapped class: Model.Prato.pedidoPratos[Model.PedidoPrato]".

Já procurei esse erro no fórum e vi que o problema podia ser que a classe não estar mapeada no .xml do hibernate, porém a classe está mapeada sim.

Eu tenho as seguintes classes: Pedido, PedidoPrato, Prato, PratoInsumo e Insumo.

1 Pedido tem vários Pratos, por isso criei a classe PedidoPrato, assim como 1 Prato tem vários Insumos, por isso criei a clase PratoInsumo.
As classes PedidoPrato e PratoInsumo são associativas.

Vocês podem me ajudar nesse problema?

Seguem as classes e o mapeamento do hibernate

Pedido:
package Model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.*;
import org.apache.log4j.Logger;

@Entity
@Table(name = "pedido")
@SequenceGenerator(name = "sequencia", sequenceName = "seq_pedido_id")
public class Pedido implements Serializable{
    
    private static Logger logger = Logger.getLogger(Pedido.class);
    private Long idPedido;
    private Date dataPedido;
    private Cliente cliente;
    private Funcionario funcionario;
    private List<PedidoPrato> pedidoPratos = new ArrayList<PedidoPrato>();
    
    @Id
    public Long getIdPedido() {
        return idPedido;
    }

    public void setIdPedido(Long idPedido) {
        this.idPedido = idPedido;
    }

    @OneToOne(fetch= FetchType.LAZY)
    @JoinColumn(name="idCliente",nullable=true)
    public Cliente getCliente() {
        return cliente;
    }
    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    @OneToOne(fetch= FetchType.LAZY)
    @JoinColumn(name="idFuncionario",nullable=true)
    public Funcionario getFuncionario() {
        return funcionario;
    }
    public void setFuncionario(Funcionario funcionario) {
        this.funcionario = funcionario;
    }
   
    @Temporal(javax.persistence.TemporalType.DATE)
    public Date getDataPedido() {
        return dataPedido;
    }

    public void setDataPedido(Date dataPedido) {
        this.dataPedido = dataPedido;
    }


    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pedido")
    public List<PedidoPrato> getPedidoPratos() {
        return pedidoPratos;
    }

    public void setPedidoPratos(List<PedidoPrato> pedidoPratos) {
        this.pedidoPratos = pedidoPratos;
    }

}
PedidoPrato:
package Model;

import java.io.Serializable;
import javax.persistence.*;

@Entity
@Table(name = "pedidoprato")
@SequenceGenerator(name="sequencia",sequenceName="seq_pedpra_id")
public class PedidoPrato implements Serializable {

    private Integer id;
    private Prato prato;
    private Pedido pedido;
    private int quantidade;

    @Id
    @GeneratedValue(strategy= GenerationType.SEQUENCE,generator="sequencia")
    public Integer getId() {
        return id;
    }

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="idPedido",nullable=true)
    public Pedido getPedido() {
        return pedido;
    }

    public void setPedido(Pedido pedido) {
        this.pedido = pedido;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="idPrato",nullable=true)
    public Prato getPrato() {
        return prato;
    }

    public void setPrato(Prato prato) {
        this.prato = prato;
    }

    @Column(name="quantidade")
    public int getQuantidade() {
        return quantidade;
    }
    public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
    }
}
Prato:
package Model;

import java.io.Serializable;
import java.sql.Time;
import java.util.*;
import javax.persistence.*;
import util.HibernateUtil;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

@Entity
@Table(name = "prato")
@SequenceGenerator(name = "sequencia", sequenceName = "seq_prato_id")
public class Prato implements Serializable {

    private static Logger logger = Logger.getLogger(Prato.class);
    private Long idPrato;
    private String nomePrato;
    private String modoPreparo;
    private Integer dificuldade;
    private Integer porcoes;
    private Time tempoPreparo;
    private Date dataCadastro;
    private Float custoAlimentar;
    private Float custoMaoDeObra;
    private Float custoIndireto;
    private Float custoTotal;
    private Float lucroPorcao;
    private Float lucroPrato;
    private Float margemLucroPrato;
    private Float margemLucroPorcao;
    private Float precoVendaPorcao;
    private Float precoVendaPrato;
    private List<PratoInsumo> pratoInsumos = new ArrayList<PratoInsumo>();
    private List<PedidoPrato> pedidoPratos = new ArrayList<PedidoPrato>();

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequencia")
    public Long getIdPrato() {
        return idPrato;
    }

    public void setIdPrato(Long idPrato) {
        this.idPrato = idPrato;
    }

    @Temporal(javax.persistence.TemporalType.DATE)
    public Date getDataCadastro() {
        return dataCadastro;
    }

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

    public String getModoPreparo() {
        return modoPreparo;
    }

    public void setModoPreparo(String modoPreparo) {
        this.modoPreparo = modoPreparo;
    }

    public String getNomePrato() {
        return nomePrato;
    }

    public void setNomePrato(String nomePrato) {
        this.nomePrato = nomePrato;
    }

    public Integer getDificuldade() {
        return dificuldade;
    }

    public void setDificuldade(Integer dificuldade) {
        this.dificuldade = dificuldade;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        Prato.logger = logger;
    }

    public Integer getPorcoes() {
        return porcoes;
    }

    public void setPorcoes(Integer porcoes) {
        this.porcoes = porcoes;
    }

    public Time getTempoPreparo() {
        return tempoPreparo;
    }

    public void setTempoPreparo(Time tempoPreparo) {
        this.tempoPreparo = tempoPreparo;
    }
    
    
    public Float getCustoAlimentar() {
        return custoAlimentar;
    }

    public void setCustoAlimentar(Float custoAlimentar) {
        this.custoAlimentar = custoAlimentar;
    }

    public Float getCustoIndireto() {
        return custoIndireto;
    }

    public void setCustoIndireto(Float custoIndireto) {
        this.custoIndireto = custoIndireto;
    }

    public Float getCustoMaoDeObra() {
        return custoMaoDeObra;
    }

    public void setCustoMaoDeObra(Float custoMaoDeObra) {
        this.custoMaoDeObra = custoMaoDeObra;
    }

    public Float getCustoTotal() {
        return custoTotal;
    }

    public void setCustoTotal(Float custoTotal) {
        this.custoTotal = custoTotal;
    }

    public Float getLucroPorcao() {
        return lucroPorcao;
    }

    public void setLucroPorcao(Float lucroPorcao) {
        this.lucroPorcao = lucroPorcao;
    }

    public Float getLucroPrato() {
        return lucroPrato;
    }

    public void setLucroPrato(Float lucroPrato) {
        this.lucroPrato = lucroPrato;
    }

    
    public Float getMargemLucroPorcao() {
        return margemLucroPorcao;
    }

    public void setMargemLucroPorcao(Float margemLucroPorcao) {
        this.margemLucroPorcao = margemLucroPorcao;
    }

    public Float getMargemLucroPrato() {
        return margemLucroPrato;
    }

    public void setMargemLucroPrato(Float margemLucroPrato) {
        this.margemLucroPrato = margemLucroPrato;
    }
    public Float getPrecoVendaPorcao() {
        return precoVendaPorcao;
    }

    public void setPrecoVendaPorcao(Float precoVendaPorcao) {
        this.precoVendaPorcao = precoVendaPorcao;
    }

    public Float getPrecoVendaPrato() {
        return precoVendaPrato;
    }

    public void setPrecoVendaPrato(Float precoVendaPrato) {
        this.precoVendaPrato = precoVendaPrato;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "prato")
    public List<PratoInsumo> getPratoInsumos() {
        return pratoInsumos;
    }

    public void setPratoInsumos(List<PratoInsumo> pratoInsumos) {
        this.pratoInsumos = pratoInsumos;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "prato")
    public List<PedidoPrato> getPedidoPratos() {
        return pedidoPratos;
    }

    public void setPedidoPratos(List<PedidoPrato> pedidoPratos) {
        this.pedidoPratos = pedidoPratos;
    }
    
}
PratoInsumo:
package Model;

import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.*;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import util.HibernateUtil;

@Entity
@Table(name = "pratoinsumo")
@SequenceGenerator(name="sequencia",sequenceName="seq_prains_id")
public class PratoInsumo implements Serializable {

    private Integer id;
    private Prato prato;
    private Insumo insumo;
    private int quantidade;
    
    @Id
    @GeneratedValue(strategy= GenerationType.SEQUENCE,generator="sequencia")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="idInsumo",nullable=true)
    public Insumo getInsumo() {
        return insumo;
    }

    public void setInsumo(Insumo insumo) {
        this.insumo = insumo;
    }
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="idPrato",nullable=true)
    public Prato getPrato() {
        return prato;
    }

    public void setPrato(Prato prato) {
        this.prato = prato;
    }
    
    @Column(name="quantidade")
    public int getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
    }
}

Insumo:

package Model;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.*;
import org.apache.log4j.Logger;
import org.hibernate.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.criterion.Projections;
import util.HibernateUtil;


@Entity
@Table(name="insumo")
@SequenceGenerator(name="sequencia",sequenceName="seq_ins_id")
public class Insumo implements Serializable {

    private static Logger logger = Logger.getLogger(Insumo.class);
    private Long idInsumo;
    private String nomeInsumo;
    private String unidadeMedida;
    private String grupoInsumo;
    private int valorEnergetico;
    private float proteinas;
    private float lipideos;
    private float carboidratos;
    private float calcio;
    private float ferro;
    private float sodio;
    private float valorInsumo;
    private Date dtCadastro;
    private List<PratoInsumo> pratoInsumos = new ArrayList<PratoInsumo>();

    public float getCalcio() {
        return calcio;
    }

    public void setCalcio(float calcio) {
        this.calcio = calcio;
    }

    public float getCarboidratos() {
        return carboidratos;
    }

    public void setCarboidratos(float carboidratos) {
        this.carboidratos = carboidratos;
    }

    public float getFerro() {
        return ferro;
    }

    public void setFerro(float ferro) {
        this.ferro = ferro;
    }
    
    @Id
    @GeneratedValue(strategy= GenerationType.SEQUENCE,generator="sequencia")
    public Long getIdInsumo() {
        return idInsumo;
    }

    public void setIdInsumo(Long idInsumo) {
        this.idInsumo = idInsumo;
    }

    public float getLipideos() {
        return lipideos;
    }

    public void setLipideos(float lipideos) {
        this.lipideos = lipideos;
    }

    public String getNomeInsumo() {
        return nomeInsumo;
    }

    public void setNomeInsumo(String nomeInsumo) {
        this.nomeInsumo = nomeInsumo;
    }

    public float getProteinas() {
        return proteinas;
    }

    public void setProteinas(float proteinas) {
        this.proteinas = proteinas;
    }

    public float getSodio() {
        return sodio;
    }

    public void setSodio(float sodio) {
        this.sodio = sodio;
    }

    public String getUnidadeMedida() {
        return unidadeMedida;
    }

    public void setUnidadeMedida(String unidadeMedida) {
        this.unidadeMedida = unidadeMedida;
    }

    public int getValorEnergetico() {
        return valorEnergetico;
    }

    public void setValorEnergetico(int valorEnergetico) {
        this.valorEnergetico = valorEnergetico;
    }

    public float getValorInsumo() {
        return valorInsumo;
    }

    public void setValorInsumo(float valorInsumo) {
        this.valorInsumo = valorInsumo;
    }
    public String getGrupoInsumo() {
        return grupoInsumo;
    }

    public void setGrupoInsumo(String grupoInsumo) {
        this.grupoInsumo = grupoInsumo;
    }
    
    @Temporal(javax.persistence.TemporalType.DATE)
    public Date getDtCadastro() {
        return dtCadastro;
    }

    public void setDtCadastro(Date dtCadastro) {
        this.dtCadastro = dtCadastro;
    }

    @OneToMany(cascade=CascadeType.ALL,fetch= FetchType.LAZY,mappedBy="insumo")
    public List<PratoInsumo> getPratoInsumos() {
        return pratoInsumos;
    }

    public void setPratoInsumos(List<PratoInsumo> pratoInsumos) {
        this.pratoInsumos = pratoInsumos;
    }
}
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/Nutrys</property>
    <property name="hibernate.connection.username">postgres</property>
    <property name="hibernate.connection.password">postgres</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.show_sql">true</property>
    <mapping class="Model.Funcionario"/>
    <mapping class="Model.Insumo"/>
    <mapping class="Model.Prato"/>
    <mapping class="Model.PratoInsumo"/>
    <mapping class="Model.Pedido"/>
    <mapping class="Model.Cliente"/>
    <mapping class="Model.PedidoPrato"/>
  </session-factory>
</hibernate-configuration>

11 Respostas

romarcio

Quando você usa Hibernate e tem um relaciomamento N-N, não precisa mapear a tabela de relacionamento criada no banco. No caso você tem Prato e Pedido. Criou a tabela PedidoPrato, essa tabela deve conter apenas o idPrato e o idPedido, então não tem porque mapea-la e nem criar uma classe para ela no sistema. O próprio hibernate cuida disso para você.

Para isso, na classe Prato faça assim:

@ManyToMany(mappedBy = "pratos")
    private Collection&lt;Pedido&gt; pedidos= new ArrayList&lt;Pedido&gt;();

E na classe Pedido:

@ManyToMany(targetEntity = Prato.class)
    @JoinTable(
            name = "PEDIDO_PRATO",
            joinColumns = @JoinColumn(name = "ID_PEDIDO"),
            inverseJoinColumns = @JoinColumn(name = "ID_PRATO")
    )
    private Collection&lt;Prato&gt; pratos= new ArrayList&lt;Prato&gt;();
hugo.hlcxcx

cara, olhando apenas superficialmente eu achei desnecessária a criação da classe Pedido Prato. Acho que seria mais correto se vc criasse uma coleção de Pratos dentro de Pedido com relacionamento 1 : N ao invés de PedidoPrato como foi implementado.

N

Pessoal,

Entendo e agradeço a visão de vocês, mas o problema é que preciso criar a clase PedidoPrato porque eu preciso da quantidade de cada Prato daquele Pedido, por isso criei a classe com o atributo quantidade dentro.

Um pedido pode ter mais de um prato e cada prato dentro desse pedido tem uma quantidade que pode ser maior que um.
Exemplo de pedido:
4 X-Mignon
2 Porções de fritas
4 Sucos de Laranja

Eu consigo trazer a quantidade de cada prato para dentro da classe Pedido?

Não consigo visualizar isso.

Abraço.

romarcio

Então, faz como eu te disse. Você vai ter uma lista de Pratos na classe Pedido. Para cada Pedido localizado em uma consulta, você vai poder ter acesso a lista de pratos desse pedido.

N

Sim eu consigo ter uma lista de pratos do pedido, mas não consigo ter a quantidade de cada prato desse pedido.
O meu problema agora está na quantidade de cada prato.

romarcio

nevescwb:
Sim eu consigo ter uma lista de pratos do pedido, mas não consigo ter a quantidade de cada prato desse pedido.
O meu problema agora está na quantidade de cada prato.

Então me diga uma coisa. Se você tivesse uma classe PedidoPrato, como saberia a quantidade de cada prato em um mesmo pedido?

N

Então, eu esqueci de mencionar mas eu já fiz a mesma coisa para Prato x PratoInsumo x Insumo.

A minha tabela pratoinsumo fica assim (não consegui anexar a imagem da tabela então vai assim mesmo):

idprato || idinsumo || quantidade || id

1050 || 188 || 7 ||850
1050 || 189 || 9 ||851
1050 || 244 || 9 ||852
1100 || 244 || 5 ||900
1150 || 12250 || 12 ||950
1150 || 12251 || 34 ||951
1200 || 244 || 2 ||1000
1200 || 12500 || 6 ||1001
1250 || 12300 || 7 ||1050
1250 || 12450 || 6 ||1051

O que é feito na PratoInsumo eu preciso que seja feito na PedidoPrato, porém não estou conseguindo, e fiz tudo igual nas 2.

romarcio

Se você vai usar mais colunas além do ID e precisa manipula-las, então tem que fazer como está fazendo.
Para corrigir o erro que você postou, tenta alterar na classe Prato a anotação @OneToMany.
Na classe Prato altera para isso:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "prato", targetEntity = PedidoPrato.class)  
    public List&lt;PedidoPrato&gt; getPedidoPratos() {  
        return pedidoPratos;  
    }
N

Se você vai usar mais colunas além do ID e precisa manipula-las, então tem que fazer como está fazendo.
Para corrigir o erro que você postou, tenta alterar na classe Prato a anotação @OneToMany.
Na classe Prato altera para isso:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "prato", targetEntity = PedidoPrato.class)     
  public List<PedidoPrato> getPedidoPratos() {     
      return pedidoPratos;     
  }

Tentei mas continua dando o mesmo erro =/
já não sei mais o que fazer!!

romarcio

Não consigo ver outra coisa que pudesse estar ocasionando esse erro.

N

Alguém me ajuda?

Criado 1 de outubro de 2011
Ultima resposta 2 de out. de 2011
Respostas 11
Participantes 3