Mapeamento Many-to-Many com herança - Modo de mapeamento por tabela única

       Estou tentando implementar a seguinte estrutura utilizando Java, Hibernate e PostgreSql.

Classe ProdutoBean:

@Entity
@Table(name = “produto”)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = “type”, discriminatorType = DiscriminatorType.STRING)
public abstract class ProdutoBean implements Serializable {
private Integer codigo;
private String nome;
private Float estoqueMinino;
private Float estoqueMaximo;
private String observacao;
private Float precoCusto;
private UnidadeBean unidade;
private Float quantidade;

@Id
@SequenceGenerator(name="seq_produto", sequenceName="produto_codigo_seq")
@GeneratedValue(generator="seq_produto")
@Column(name="codigo")
public Integer getCodigo() {
    return codigo;
}

public void setCodigo(Integer codigo) {
    this.codigo = codigo;
}

@Column(name="estoquemaximo")
public Float getEstoqueMaximo() {
    return estoqueMaximo;
}

public void setEstoqueMaximo(Float estoqueMaximo) {
    this.estoqueMaximo = estoqueMaximo;
}

@Column(name="estoqueminimo")
public Float getEstoqueMinino() {
    return estoqueMinino;
}

public void setEstoqueMinino(Float estoqueMinino) {
    this.estoqueMinino = estoqueMinino;
}

@Column(name="nome")
public String getNome() {
    return nome;
}

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

@Column(name="observacao")
public String getObservacao() {
    return observacao;
}

public void setObservacao(String observacao) {
    this.observacao = observacao;
}

@Column(name="precocusto")
public Float getPrecoCusto() {
    return precoCusto;
}

public void setPrecoCusto(Float precoCusto) {
    this.precoCusto = precoCusto;
}

@Column(name="quantidade")
public Float getQuantidade() {
    return quantidade;
}

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

@ManyToOne
@JoinColumn(name="codunidade")
public UnidadeBean getUnidade() {
    return unidade;
}

public void setUnidade(UnidadeBean unidade) {
    this.unidade = unidade;
}

@Override
public String toString(){
    return getNome();
}

}

Classe ProdutoIngredienteBean

@Entity
@DiscriminatorValue(“ProdutoIngrediente”) //é referenciado ao type
public class ProdutoIngredienteBean extends ProdutoBean{

@ManyToMany
@JoinTable(name = "pratoprodutoingrediente",
joinColumns = {
@JoinColumn(name = "codprodutoingrediente")},
inverseJoinColumns = {
@JoinColumn(name = "codprato")})
private Collection<PratoBean> pratos;

public Collection<PratoBean> getPratos() {
    return pratos;
}

public void setPratos(Collection<PratoBean> pratos) {
    this.pratos = pratos;
}

}

Classe PratoBean

@Entity
@Table(name = “prato”)
public class PratoBean implements Serializable{

@Id
@Column(name = "codigo")
@SequenceGenerator(name = "seq_prato", sequenceName = "prato_codigo_seq")
@GeneratedValue(generator = "seq_prato")
private Integer codigo;

@Column(name = "identificacao")
private String identificacao;

@Column(name = "descricao")
private String descricao;

@Column(name = "precovenda")
private Float precoVenda;

@Column(name = "tempopreparo")
private Integer tempoPreparo;

@Column(name = "promocao")
private Short promocao;

@Column(name = "valorpromocao")
private Float valorPromocao;

@ManyToOne
@JoinColumn(name="codcategoria")
private CategoriaBean categoria;

@ManyToMany
@JoinTable(name = "pratoprodutoingrediente",
joinColumns = {
@JoinColumn(name = "codprato")},
inverseJoinColumns = {
@JoinColumn(name = "codprodutoingrediente")})    
private Collection<ProdutoIngredienteBean> produtosIngredientes;

public CategoriaBean getCategoria() {
    return categoria;
}

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

public Integer getCodigo() {
    return codigo;
}

public void setCodigo(Integer codigo) {
    this.codigo = codigo;
}

public String getDescricao() {
    return descricao;
}

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

public String getIdentificacao() {
    return identificacao;
}

public void setIdentificacao(String identificacao) {
    this.identificacao = identificacao;
}

public Float getPrecoVenda() {
    return precoVenda;
}

public void setPrecoVenda(Float precoVenda) {
    this.precoVenda = precoVenda;
}

public Collection getProdutosIngredientes() {
    return produtosIngredientes;
}

public void setProdutosIngredientes(Collection produtosIngredientes) {
    this.produtosIngredientes = produtosIngredientes;
}

public Short getPromocao() {
    return promocao;
}

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

public Integer getTempoPreparo() {
    return tempoPreparo;
}

public void setTempoPreparo(Integer tempoPreparo) {
    this.tempoPreparo = tempoPreparo;
}

public Float getValorPromocao() {
    return valorPromocao;
}

public void setValorPromocao(Float valorPromocao) {
    this.valorPromocao = valorPromocao;
}

}

Classe de Associação PratoProdutoIngredienteBean

@Entity
@Table(name = “pratoprodutoingrediente”)
public class PratoProdutoIngredienteBean implements Serializable{

@EmbeddedId
private PratoProdutoIngredientePK chaveComposta;

@Column(name = "quantidade")
private Float quantidade;

public Float getQuantidade() {
    return quantidade;
}

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

/**
 * @return the chaveComposta
 */
public PratoProdutoIngredientePK getChaveComposta() {
    return chaveComposta;
}

/**
 * @param chaveComposta the chaveComposta to set
 */
public void setChaveComposta(PratoProdutoIngredientePK chaveComposta) {
    this.chaveComposta = chaveComposta;
}

}

Classe para mapear a chave composta
@Embeddable
public class PratoProdutoIngredientePK implements Serializable {

@ManyToOne()
@JoinColumn(name = "codprato")
private PratoBean prato;

@ManyToOne
@JoinColumn(name = "codprodutoingrediente")
private ProdutoIngredienteBean produtoIngrediente;

/**
 * @return the prato
 */
public PratoBean getPrato() {
    return prato;
}

/**
 * @param prato the prato to set
 */
public void setPrato(PratoBean prato) {
    this.prato = prato;
}

/**
 * @return the produtoIngrediente
 */
public ProdutoIngredienteBean getProdutoIngrediente() {
    return produtoIngrediente;
}

/**
 * @param produtoIngrediente the produtoIngrediente to set
 */
public void setProdutoIngrediente(ProdutoIngredienteBean produtoIngrediente) {
    this.produtoIngrediente = produtoIngrediente;
}

}

Script das tabelas no banco:

Tabela utilizada para armazenar objetos das classes ProdutoBean e ProdutoIngredienteBean
create table “produto” (
“codigo” serial not null,
“nome” varchar,
“estoqueminimo” numeric(20,2),
“observacao” varchar,
“precocusto” numeric(20,2),
“quantidade” numeric(20,2),
“precovenda” numeric(20,2),
“margemlucro” numeric(20,2),
“promocao” int2,
“valorpromocao” numeric(20,2),
“identificacao” varchar,
“type” varchar,
“codunidade” int4 not null,
primary key(“codigo”)
);

alter table “produto” add constraint “ref_produto_to_unidade” foreign key (“codunidade”)
references “unidade”(“codigo”)
match simple
on delete no action
on update no action
not deferrable;

Tabela usada para armazenar objetos da classe PratoBean
create table “prato” (
“codigo” serial not null,
“identificacao” varchar,
“descricao” varchar,
“precovenda” numeric(20,2),
“tempopreparo” int2,
“promocao” int2,
“valorpromocao” numeric(20,2),
“categoriaimpressao” int2,
“codcategoria” int4,
primary key(“codigo”)
);

alter table “prato” add constraint “ref_prato_to_categoria” foreign key (“codcategoria”)
references “categoria”(“codigo”)
match simple
on delete no action
on update cascade
not deferrable;

Tabela para armazenar dados da associação Many-to-Many de ProdutoIngredienteBean e PratoBean
create table “pratoprodutoingrediente” (
“codprato” int4,
“codprodutoingrediente” int4,
“quantidade” numeric(20,2) not null
);

alter table “pratoprodutoingrediente” add constraint “ref_pratoprodutoingrediente_to_prato” foreign key (“codprato”)
references “prato”(“codigo”)
match simple
on delete no action
on update cascade
not deferrable;

alter table “pratoprodutoingrediente” add constraint “ref_pratoprodutoingrediente_to_produto” foreign key (“codprodutoingrediente”)
references “produto”(“codigo”)
match simple
on delete no action
on update cascade
not deferrable;

Faço todos o mapeamento com Hibernate mas quando vou testar qualquer operação com Hibernate, dá o seguinte erro:

Could not determine type for: java.util.Collection, at table: produto, for columns: [org.hibernate.mapping.Column(pratos)]
at util.Conexao.(Conexao.java:20)
at util.BaseDaoImpl.inserir(BaseDaoImpl.java:34)
at Main3.main(Main3.java:38)
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Collection, at table: produto, for columns: [org.hibernate.mapping.Column(pratos)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:276)
at org.hibernate.mapping.Property.isValid(Property.java:207)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:458)
at org.hibernate.mapping.SingleTableSubclass.validate(SingleTableSubclass.java:66)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1135)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1320)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
at util.Conexao.(Conexao.java:15)
… 2 more
Java Result: 1
CONSTRUÍDO COM SUCESSO (tempo total: 1 segundo)

Alguém sabe me dizer o que pode está havendo.

Fico no aguardo do retorno.
Abs,
Pierre Viana,