Problemas com Relação N:N usando Hibernate

18 respostas
Jackye

Olá!

Estou criando uma aplicação desktop de controle bibliotecário.
Utilizo NetBeans 7.0 + Hibernate + SQL Server 2008.

A aplicação tem uma superclasse chamada ItemBiblioteca que tem um relacionamento N:N com a classe autor, portanto no banco de dados foi feito uma tabela chamada ItemBibliotecaAutor, só que a superclasse não recebe FK de Autor!!
As subclasses, como livro, revista e etc que herdam atributos da superclasse também não estão buscando o CodAutor.

Automaticamente a Classe Autor gerou o seguinte código para o relacionamento N:N:

@JoinTable(name = "ItemBibliotecaAutor", joinColumns = { @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = { @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)}) @ManyToMany private Collection<ItemBiblioteca> itemBibliotecaCollection;
E a classe Itembiblioteca gerou o seguinte:

ManyToMany(mappedBy = "itemBibliotecaCollection") private Collection<Autor> autorCollection;

:cry: Ajudem me.

18 Respostas

Hebert_Coelho

A chave fica no lado que “domina” o relacionamento.

Nesse caso o lado que é “submisso” é o lado em que tem o mappedBy. É por isos que você só vê a chave de um lado.

Qual o problema em ter a chave em apenas de um lado?

drsmachado

Jackye:
Olá!

Estou criando uma aplicação desktop de controle bibliotecário.
Utilizo NetBeans 7.0 + Hibernate + SQL Server 2008.

A aplicação tem uma superclasse chamada ItemBiblioteca que tem um relacionamento N:N com a classe autor, portanto no banco de dados foi feito uma tabela chamada ItemBibliotecaAutor, só que a superclasse não recebe FK de Autor!!
As subclasses, como livro, revista e etc que herdam atributos da superclasse também não estão buscando o CodAutor.

Automaticamente a Classe Autor gerou o seguinte código para o relacionamento N:N:

@JoinTable(name = "ItemBibliotecaAutor", joinColumns = { @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = { @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)}) @ManyToMany private Collection<ItemBiblioteca> itemBibliotecaCollection;
E a classe Itembiblioteca gerou o seguinte:

ManyToMany(mappedBy = "itemBibliotecaCollection") private Collection<Autor> autorCollection;

:cry: Ajudem me.


Se o problema é este…
Eu simplesmente faria isso, manualmente:

@JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)})
    @ManyToMany
    private Collection<ItemBiblioteca> itemBibliotecaCollection;

E na classe ItemBiblioteca

@JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)})
    @ManyToMany
    private Collection<Autor> autorCollection;
Jackye

Olá, drsmachado.

Fiz manualmente o código na classe ItemBiblioteca, mas não funcionou. :frowning:
Será que é por que o código da classe autor não aparece na Classe ItemBiblioteca?
A seguir estão os códigos:

CLASSE AUTOR:

package br.com.Dominio;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@Table(name = "Autor", catalog = "dbControleBibliotecario", schema = "dbo")

public class Autor implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @Basic(optional = false)
    @Column(name = "CodAutor", nullable = false)
    private Integer codAutor;
    @Basic(optional = false)
    @Column(name = "NomeAutor", nullable = false, length = 255)
    private String nomeAutor;
    @Basic(optional = false)
    @Column(name = "DataCadastro", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataCadastro;
    
    //Annotation para relacionamento N:N
    @JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)})
    @ManyToMany
    private Collection<ItemBiblioteca> itemBibliotecaCollection;                                  
    

    public Autor() {
    }

    public Autor(Integer codAutor) {
        this.codAutor = codAutor;
    }

    public Autor(Integer codAutor, String nomeAutor, Date dataCadastro) {
        this.codAutor = codAutor;
        this.nomeAutor = nomeAutor;
        this.dataCadastro = dataCadastro;
    }

    public Integer getCodAutor() {
        return codAutor;
    }

    public void setCodAutor(Integer codAutor) {
        this.codAutor = codAutor;
    }

    public String getNomeAutor() {
        return nomeAutor;
    }

    public void setNomeAutor(String nomeAutor) {
        this.nomeAutor = nomeAutor;
    }

    public Date getDataCadastro() {
        return dataCadastro;
    }

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

    @XmlTransient
    public Collection<ItemBiblioteca> getItemBibliotecaCollection() {
        return itemBibliotecaCollection;
    }

    public void setItemBibliotecaCollection(Collection<ItemBiblioteca> itemBibliotecaCollection) {
        this.itemBibliotecaCollection = itemBibliotecaCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (codAutor != null ? codAutor.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Autor)) {
            return false;
        }
        Autor other = (Autor) object;
        if ((this.codAutor == null && other.codAutor != null) || (this.codAutor != null && !this.codAutor.equals(other.codAutor))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.com.Dominio.Autor[ codAutor=" + codAutor + " ]";
    }
    
}

CLASSE ITEMBIBLIOTECA:

package br.com.Dominio;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@Table(name = "ItemBiblioteca", catalog = "dbControleBibliotecario", schema = "dbo")
@Inheritance(strategy= InheritanceType.JOINED)
@XmlRootElement

public class ItemBiblioteca implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @Basic(optional = false)
    @Column(name = "CodItemBiblioteca", nullable = false)
    private Integer codItemBiblioteca;
    @Basic(optional = false)
    @Column(name = "Titulo", nullable = false, length = 150)
    private String titulo;
    @Basic(optional = false)
    @Column(name = "NuReferencia", nullable = false)
    private int nuReferencia;
    @Basic(optional = false)
    @Column(name = "Edicao", nullable = false)
    private int edicao;
    @Basic(optional = false)
    @Column(name = "AnoEdicao", nullable = false)
    private int anoEdicao;
    @Basic(optional = false)
    @Column(name = "NumeroExemplar", nullable = false)
    private int numeroExemplar;
    @Column(name = "Observacao", length = 255)
    private String observacao;
    @Basic(optional = false)
    @Column(name = "DataCadastro", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataCadastro;
    
    //Annotation para relacionamento N:N
   @JoinTable(name = "ItemBibliotecaAutor", joinColumns = {  
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)}, inverseJoinColumns = {  
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)})  
    @ManyToMany  
    private Collection<Autor> codautor;

    //Annotation para relacionamento N:1  
    @JoinColumn(name = "CodSecao", referencedColumnName = "CodSecao", nullable = false)
    @ManyToOne(optional = false)
    private Secao codSecao;

    //Annotation para relacionamento N:1
    @JoinColumn(name = "CodEditora", referencedColumnName = "CodEditora", nullable = false)
    @ManyToOne(optional = false)
    private Editora codEditora;

    public ItemBiblioteca() {
    }

    public ItemBiblioteca(Integer codItemBiblioteca) {
        this.codItemBiblioteca = codItemBiblioteca;
    }

    public ItemBiblioteca(Integer codItemBiblioteca, String titulo, int nuReferencia, int edicao, int anoEdicao, int numeroExemplar, Date dataCadastro) {
        this.codItemBiblioteca = codItemBiblioteca;
        this.titulo = titulo;
        this.nuReferencia = nuReferencia;
        this.edicao = edicao;
        this.anoEdicao = anoEdicao;
        this.numeroExemplar = numeroExemplar;
        this.dataCadastro = dataCadastro;
    }

    public Integer getCodItemBiblioteca() {
        return codItemBiblioteca;
    }

    public void setCodItemBiblioteca(Integer codItemBiblioteca) {
        this.codItemBiblioteca = codItemBiblioteca;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public int getNuReferencia() {
        return nuReferencia;
    }

    public void setNuReferencia(int nuReferencia) {
        this.nuReferencia = nuReferencia;
    }

    public int getEdicao() {
        return edicao;
    }

    public void setEdicao(int edicao) {
        this.edicao = edicao;
    }

    public int getAnoEdicao() {
        return anoEdicao;
    }

    public void setAnoEdicao(int anoEdicao) {
        this.anoEdicao = anoEdicao;
    }

    public int getNumeroExemplar() {
        return numeroExemplar;
    }

    public void setNumeroExemplar(int numeroExemplar) {
        this.numeroExemplar = numeroExemplar;
    }

    public String getObservacao() {
        return observacao;
    }

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

    public Date getDataCadastro() {
        return dataCadastro;
    }

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

    @XmlTransient
    public Collection<Autor> gecodautor() {
        return codautor;
    }

    public void setcodautor(Collection<Autor> codautor) {
        this.codautor= codautor;
    }

    public Secao getCodSecao() {
        return codSecao;
    }

    public void setCodSecao(Secao codSecao) {
        this.codSecao = codSecao;
    }

    public Editora getCodEditora() {
        return codEditora;
    }

    public void setCodEditora(Editora codEditora) {
        this.codEditora = codEditora;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (codItemBiblioteca != null ? codItemBiblioteca.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof ItemBiblioteca)) {
            return false;
        }
        ItemBiblioteca other = (ItemBiblioteca) object;
        if ((this.codItemBiblioteca == null && other.codItemBiblioteca != null) || (this.codItemBiblioteca != null && !this.codItemBiblioteca.equals(other.codItemBiblioteca))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.com.Dominio.ItemBiblioteca[ codItemBiblioteca=" + codItemBiblioteca + " ]";
    }
    
}

E aí?
O que faço? :frowning:

drsmachado

Jackye:
Olá, drsmachado.

Fiz manualmente o código na classe ItemBiblioteca, mas não funcionou. :frowning:
Será que é por que o código da classe autor não aparece na Classe ItemBiblioteca?
A seguir estão os códigos:

CLASSE AUTOR:

package br.com.Dominio;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@Table(name = "Autor", catalog = "dbControleBibliotecario", schema = "dbo")

public class Autor implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @Basic(optional = false)
    @Column(name = "CodAutor", nullable = false)
    private Integer codAutor;
    @Basic(optional = false)
    @Column(name = "NomeAutor", nullable = false, length = 255)
    private String nomeAutor;
    @Basic(optional = false)
    @Column(name = "DataCadastro", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataCadastro;
    
    //Annotation para relacionamento N:N
    @JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)})
    @ManyToMany
    private Collection<ItemBiblioteca> itemBibliotecaCollection;                                  
    

    public Autor() {
    }

    public Autor(Integer codAutor) {
        this.codAutor = codAutor;
    }

    public Autor(Integer codAutor, String nomeAutor, Date dataCadastro) {
        this.codAutor = codAutor;
        this.nomeAutor = nomeAutor;
        this.dataCadastro = dataCadastro;
    }

    public Integer getCodAutor() {
        return codAutor;
    }

    public void setCodAutor(Integer codAutor) {
        this.codAutor = codAutor;
    }

    public String getNomeAutor() {
        return nomeAutor;
    }

    public void setNomeAutor(String nomeAutor) {
        this.nomeAutor = nomeAutor;
    }

    public Date getDataCadastro() {
        return dataCadastro;
    }

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

    @XmlTransient
    public Collection<ItemBiblioteca> getItemBibliotecaCollection() {
        return itemBibliotecaCollection;
    }

    public void setItemBibliotecaCollection(Collection<ItemBiblioteca> itemBibliotecaCollection) {
        this.itemBibliotecaCollection = itemBibliotecaCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (codAutor != null ? codAutor.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Autor)) {
            return false;
        }
        Autor other = (Autor) object;
        if ((this.codAutor == null && other.codAutor != null) || (this.codAutor != null && !this.codAutor.equals(other.codAutor))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.com.Dominio.Autor[ codAutor=" + codAutor + " ]";
    }
    
}

CLASSE ITEMBIBLIOTECA:

package br.com.Dominio;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@Table(name = "ItemBiblioteca", catalog = "dbControleBibliotecario", schema = "dbo")
@Inheritance(strategy= InheritanceType.JOINED)
@XmlRootElement

public class ItemBiblioteca implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @Basic(optional = false)
    @Column(name = "CodItemBiblioteca", nullable = false)
    private Integer codItemBiblioteca;
    @Basic(optional = false)
    @Column(name = "Titulo", nullable = false, length = 150)
    private String titulo;
    @Basic(optional = false)
    @Column(name = "NuReferencia", nullable = false)
    private int nuReferencia;
    @Basic(optional = false)
    @Column(name = "Edicao", nullable = false)
    private int edicao;
    @Basic(optional = false)
    @Column(name = "AnoEdicao", nullable = false)
    private int anoEdicao;
    @Basic(optional = false)
    @Column(name = "NumeroExemplar", nullable = false)
    private int numeroExemplar;
    @Column(name = "Observacao", length = 255)
    private String observacao;
    @Basic(optional = false)
    @Column(name = "DataCadastro", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataCadastro;
    
    //Annotation para relacionamento N:N
   @JoinTable(name = "ItemBibliotecaAutor", joinColumns = {  
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)}, inverseJoinColumns = {  
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)})  
    @ManyToMany  
    private Collection<Autor> codautor;

    //Annotation para relacionamento N:1  
    @JoinColumn(name = "CodSecao", referencedColumnName = "CodSecao", nullable = false)
    @ManyToOne(optional = false)
    private Secao codSecao;

    //Annotation para relacionamento N:1
    @JoinColumn(name = "CodEditora", referencedColumnName = "CodEditora", nullable = false)
    @ManyToOne(optional = false)
    private Editora codEditora;

    public ItemBiblioteca() {
    }

    public ItemBiblioteca(Integer codItemBiblioteca) {
        this.codItemBiblioteca = codItemBiblioteca;
    }

    public ItemBiblioteca(Integer codItemBiblioteca, String titulo, int nuReferencia, int edicao, int anoEdicao, int numeroExemplar, Date dataCadastro) {
        this.codItemBiblioteca = codItemBiblioteca;
        this.titulo = titulo;
        this.nuReferencia = nuReferencia;
        this.edicao = edicao;
        this.anoEdicao = anoEdicao;
        this.numeroExemplar = numeroExemplar;
        this.dataCadastro = dataCadastro;
    }

    public Integer getCodItemBiblioteca() {
        return codItemBiblioteca;
    }

    public void setCodItemBiblioteca(Integer codItemBiblioteca) {
        this.codItemBiblioteca = codItemBiblioteca;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public int getNuReferencia() {
        return nuReferencia;
    }

    public void setNuReferencia(int nuReferencia) {
        this.nuReferencia = nuReferencia;
    }

    public int getEdicao() {
        return edicao;
    }

    public void setEdicao(int edicao) {
        this.edicao = edicao;
    }

    public int getAnoEdicao() {
        return anoEdicao;
    }

    public void setAnoEdicao(int anoEdicao) {
        this.anoEdicao = anoEdicao;
    }

    public int getNumeroExemplar() {
        return numeroExemplar;
    }

    public void setNumeroExemplar(int numeroExemplar) {
        this.numeroExemplar = numeroExemplar;
    }

    public String getObservacao() {
        return observacao;
    }

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

    public Date getDataCadastro() {
        return dataCadastro;
    }

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

    @XmlTransient
    public Collection<Autor> gecodautor() {
        return codautor;
    }

    public void setcodautor(Collection<Autor> codautor) {
        this.codautor= codautor;
    }

    public Secao getCodSecao() {
        return codSecao;
    }

    public void setCodSecao(Secao codSecao) {
        this.codSecao = codSecao;
    }

    public Editora getCodEditora() {
        return codEditora;
    }

    public void setCodEditora(Editora codEditora) {
        this.codEditora = codEditora;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (codItemBiblioteca != null ? codItemBiblioteca.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof ItemBiblioteca)) {
            return false;
        }
        ItemBiblioteca other = (ItemBiblioteca) object;
        if ((this.codItemBiblioteca == null && other.codItemBiblioteca != null) || (this.codItemBiblioteca != null && !this.codItemBiblioteca.equals(other.codItemBiblioteca))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.com.Dominio.ItemBiblioteca[ codItemBiblioteca=" + codItemBiblioteca + " ]";
    }
    
}

E aí?
O que faço? :frowning:

O que aconteceu exatamente?
Pois eu testei aqui e gerei as tabelas, sem problemas.

Jackye

Oi, drsmachado.

Não consigo inserir o código autor na hora de testar um cadastro de obra. Estou testando o cadastro de obras. E o CodAutor não tá aparecendo no cadastro. Veja agora como refiz os códigos: CLASSE AUTOR:
@JoinTable(name = "ItemBibliotecaAutor", joinColumns = {  
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = {  
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)})  
        @ManyToMany(mappedBy = "autorCollection")  
        private Collection<ItemBiblioteca> itemBibliotecaCollection;
E ainda tem um codigo de set e get:
public ItemBiblioteca getItemBibliotecaCollection() {
        return (ItemBiblioteca) itemBibliotecaCollection;
    }

    public void setItemBibliotecaCollection(Collection<ItemBiblioteca> itemBibliotecaCollection) {
        this.itemBibliotecaCollection = itemBibliotecaCollection;
    }
CLASSE ITEMBIBLIOTECA:
@ManyToMany(mappedBy = "itemBibliotecaCollection")
    private Collection<Autor> autorCollection;
E o código set e get:
public Autor getautorCollection() {
        return (Autor) autorCollection ;
    }

    public void setCodautor(Collection<Autor> autorCollection) {
        this.autorCollection = autorCollection;
    }
Quando utilizei um codigo de teste para ver se esta inserindo dados no BD deu o seguinte erro: [color=red]Illegal use of mappedBy on both sides of the relationship: br.com.Dominio.ItemBiblioteca.autorCollection[/color] Só pra saber eu usei este código para teste de inserção:
public static void main(String[] args) {
      
        
       Session secao = HibernateUtil.getSessionFactory().openSession();
        
        Editora editora = (Editora) secao.load(Editora.class, 2);
        Secao s = (Secao) secao.load(Secao.class, 2);
        TipoCDDVD CddvdTipo = (TipoCDDVD) secao.load(TipoCDDVD.class, 1);
        TipoTrabalhoCientifico tipoTrabalhoCientifico = (TipoTrabalhoCientifico) secao.load(TipoTrabalhoCientifico.class, 1);
        Collection<Autor> a = (Collection<Autor>) secao.load(Autor.class,1);
        
        TrabalhoCientificoDAO TrabDAO = new TrabalhoCientificoDAO();
        TrabalhoCientifico c =  new TrabalhoCientifico();
        c.setCodItemBiblioteca(8);
        c.setCodEditora(editora);
        c.setCodautor(a);
        c.setCodSecao(s);
        c.setTitulo("A origem");
        c.setNuReferencia(6565656);
        c.setEdicao(3);
        c.setAnoEdicao(2009);
        c.setNumeroExemplar(6);
        c.setCodTipoTrabalhoCientifico(tipoTrabalhoCientifico);
        c.setNumeroPagina(20);
        c.setDataCadastro(new Date());
        
       TrabDAO.salvar(c);}

Onde estou errando? :(

Hebert_Coelho

Sem ofensas, mas você precisa entender sobre relacionamentos.

Olha só a mensagem de erro: Illegal use of mappedBy on both sides of the relationship: br.com.Dominio.ItemBiblioteca.autorCollection .

Apenas um lado pode ter mappedBy.

Aqui tem uma série de posts que podem te ajudar… Leia ao caso que se aplica ao seu relacionamento, vai tirar e muito a suas dúvidas:
@OneToOne Unidirecional e Bidirecional, @OneToMany e @ManyToOne Unidirecional e Bidirecional, @ManyToMany Unidirecional e Bidirecional

Jackye

Oi, jakefrog.

Valeu a dica.
:thumbup:

Jackye

Olá!

Os annotation para relacionamento N:N tá assim no meu projeto:

Classe ItemBiblioteca:
@ManyToMany(mappedBy = "itemBiblioteca")
    private Collection<Autor> autor;
E o get e Set:
@XmlTransient
    public Collection<Autor> getAutorCollection() {
        return autor ;
    }

    public void setAutorCollection(Collection<Autor> autor) {
        this.autor = autor;
    }
Classe Autor:
@JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodAutor", referencedColumnName = "CodAutor", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName = "CodItemBiblioteca", nullable = false)})
    @ManyToMany
    private Collection<ItemBiblioteca> itemBiblioteca;
E os set e get:
@XmlTransient
    public Collection<ItemBiblioteca> getItemBibliotecaCollection() {
        return itemBiblioteca;
    }

    public void setItemBibliotecaCollection(Collection<ItemBiblioteca> itemBibliotecaCollection) {
        this.itemBiblioteca = itemBibliotecaCollection;
    }
Para testar se a aplicação tá cadastrando utilizei o seguinte código:
Session secao = HibernateUtil.getSessionFactory().openSession();
        
        Editora editora = (Editora) secao.load(Editora.class, 2);
        Secao s = (Secao) secao.load(Secao.class, 2);
      
        Collection<Autor> a = (Collection<Autor>) secao.load(Autor.class,1);
        
        LivroDAO livroDAO = new LivroDAO();
        Livro l =  new Livro();
        
        l.setCodItemBiblioteca(11);
        l.setCodEditora(editora);
        l.setCodSecao(s);
        l.setAutorCollection(a);
        l.setTitulo("Capitu");
        l.setNuReferencia(23424234);
        l.setEdicao(2);
        l.setAnoEdicao(1990);
        l.setNumeroExemplar(9);
        l.setVolume(1);
        l.setIsbn(234578);
        l.setDataCadastro(new Date());
       
        
        livroDAO.salvar(l);   
        
    }
Quando rodei este código acima ocorreu o seguinte erro: [color=red]Exception in thread "main" java.lang.ClassCastException: br.com.Dominio.Autor$$EnhancerByCGLIB$$ee978d92 cannot be cast to java.util.Collection at br.com.Testes.TesteConexao.main(TesteConexao.java:54)[/color] Este erro aponta para a seguinte linha do código de teste:
Collection<Autor> a = (Collection<Autor>) secao.load(Autor.class,1);

Pelo que entendi o erro diz que não há como converter a classe Autor para o tipo de coleção utilizada na opção de mapeamento.

O que devo fazer? :cry:
Ajudem-me!

drsmachado

É que você está utilizando o load, isto força o hibernate a passar o objeto pesquisado em um proxy.
Troque pelo get()

Jackye

Olá drsmachado,

fiz o que disse, trocar o load pelo get, mas continuou no mesmo erro. :frowning:

drsmachado

Jackye:
Olá drsmachado,

fiz o que disse, trocar o load pelo get, mas continuou no mesmo erro. :(

Desculpe, agora que fui ler com atenção.
Para preencher uma Collection, você precisa invocar o método list…
E não o load ou get.

Agora, se quer apenas um objeto de Autor, aí sim, utilize o get/load

Jackye

Olá, drsmachado.

Eu quero buscar apenas o código de Autor.

Como eu faço isso, já que utilizo o Collection?

:slight_smile:

drsmachado

Apenas o código?
Será preciso informar algum parâmetro que identifique o autor.
Pelo que pude perceber deste trecho

Collection<Autor> a = (Collection<Autor>) secao.load(Autor.class,1);   
           
        LivroDAO livroDAO = new LivroDAO();   
        Livro l =  new Livro();   
           
        l.setCodItemBiblioteca(11);   
        l.setCodEditora(editora);   
        l.setCodSecao(s);   
        l.setAutorCollection(a);

O que você quer é a referência para setar o id do autor na tabela de relacionamento, certo?
Se for isto, você vai precisar mesmo da lista.

Jackye

drsmachado,

e aí como faço a lista? Que tipo de lista é essa?
:slight_smile:

drsmachado

Diretamente, não há uma forma.
Será preciso utilizar Criteria ou Query

//Criteria
Criteria criteria = secao.createCriteria(Autor.class);
Collection<Autor> a = (Collection<Autor>) criteria.list();

//HQL
Query q = secao.createQuery("FROM Autor a");
Collection<Autor> a = (Collection<Autor>) q.list();

Não estou certo que funcione para Collection, mas, tenho certeza que para List funciona.

Jackye

Olá, drsmachado.

Pelo que andei pesquisando, o Hibernate não aceita identificador composto, portanto será necessário criar uma classe do tipo identificador.
Então fiz o seguinte:

Classe ItemBiblioteca:
@ManyToMany(fetch= FetchType.LAZY) 
   @JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName="CodItemBiblioteca", nullable=false)}, inverseJoinColumns = { 
        @JoinColumn(name = "CodAutor", referencedColumnName="CodAutor", nullable=false)})
   @Cascade(CascadeType.SAVE_UPDATE)
   private Collection<Autor> autor;
Get e Set:
public Collection<Autor> getCodAutor() {
        return autor ;
    }

    public void setCodAutor(Collection<Autor> autor) {
        this.autor = autor;
    }
Classe Autor:
@ManyToMany(fetch= FetchType.LAZY, mappedBy="autor") 
   @JoinTable(name = "ItemBibliotecaAutor", joinColumns = {
        @JoinColumn(name = "CodAutor", referencedColumnName="CodAutor", nullable=false)}, inverseJoinColumns = {
        @JoinColumn(name = "CodItemBiblioteca", referencedColumnName="CodItemBiblioteca", nullable=false)})
   @Cascade(CascadeType.SAVE_UPDATE)
   private Collection<ItemBiblioteca> itemBiblioteca;
Get e Set
public Collection<ItemBiblioteca> getCodItemBiblioteca() {
        return itemBiblioteca;
    }

    public void setCodItemBiblioteca(Collection<ItemBiblioteca> itemBiblioteca) {
        this.itemBiblioteca = itemBiblioteca;
    }
Classe ItemBibliotecaAutor:
@Entity
@Table(name = "ItemBibliotecaAutor")
public class ItemBibliotecaAutor implements Serializable  {

@EmbeddedId   
private ItemBibliotecaAutorPK ChaveComposta;
        
}
Classe ItemBibliotecaAutorPK:
@Embeddable
public class ItemBibliotecaAutorPK implements Serializable {
    
    @ManyToOne(fetch= FetchType.EAGER)
    @JoinColumn(name="CodAutor")
    @Cascade(CascadeType.SAVE_UPDATE)
    private Autor autor;
    
    @ManyToOne(fetch= FetchType.EAGER)
    @JoinColumn(name="CodItemBiblioteca")
    @Cascade(CascadeType.SAVE_UPDATE)
    private ItemBiblioteca itemBiblioteca;  
    
}
Rodei o meu código de teste:
Session secao = HibernateUtil.getSessionFactory().openSession();
        
        Editora editora = (Editora) secao.load(Editora.class, 2);
        Secao s = (Secao) secao.load(Secao.class, 2);
        Collection<Autor> a = (Collection<Autor>) secao.get(Autor.class, 1);
                 
        LivroDAO livroDAO = new LivroDAO();
        Livro l =  new Livro();
        
        l.setCodItemBiblioteca(11);
        l.setCodEditora(editora);
        l.setCodSecao(s);
        l.setCodAutor(a);
        l.setTitulo("Capitu");
        l.setNuReferencia(23424234);
        l.setEdicao(2);
        l.setAnoEdicao(1990);
        l.setNumeroExemplar(9);
        l.setVolume(1);
        l.setIsbn(234578);
        l.setDataCadastro(new Date());
        
        livroDAO.salvar(l);    
    }
E deu novamente o mesmo erro: [color=red]Exception in thread "main" java.lang.ClassCastException: br.com.Dominio.Autor cannot be cast to java.util.Collection at br.com.Testes.TesteConexao.main(TesteConexao.java:42) [/color] Então, utilizei os códigos da Criteria:
Session secao = HibernateUtil.getSessionFactory().openSession();
        
        Editora editora = (Editora) secao.load(Editora.class, 2);
        Secao s = (Secao) secao.load(Secao.class, 2);
        Criteria criteria = secao.createCriteria(Autor.class);  
             Collection<Autor> a = (Collection<Autor>) criteria.list();    
        
        LivroDAO livroDAO = new LivroDAO();
        Livro l =  new Livro();
        
        l.setCodItemBiblioteca(11);
        l.setCodEditora(editora);
        l.setCodSecao(s);
        l.setCodAutor(a);
        l.setTitulo("Capitu");
        l.setNuReferencia(23424234);
        l.setEdicao(2);
        l.setAnoEdicao(1990);
        l.setNumeroExemplar(9);
        l.setVolume(1);
        l.setIsbn(234578);
        l.setDataCadastro(new Date());
      
        livroDAO.salvar(l);
E deu o seguinte erro: [color=red]Exception in thread "main" org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410) at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43) at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101) at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61) at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55) at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499) at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:218) at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268) at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216) at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169) at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296) at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242) at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219) at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169) at org.hibernate.engine.Cascade.cascade(Cascade.java:130) at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456) at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:334) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187) at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172) at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519) at br.com.Persistencia.GenericHibernateDAO.salvar(GenericHibernateDAO.java:65) at br.com.Testes.TesteConexao.main(TesteConexao.java:61)[/color] Na parte [color=red]at br.com.Persistencia.GenericHibernateDAO.salvar(GenericHibernateDAO.java:65)[/color] arremete para a seguinte linha
@SuppressWarnings("unchecked")
    @Override
    public T salvar(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().save(entidade);
        transacao.commit();
        getSession().close(); 
        return entidade;
    }
Especificamente na linha
getSession().save(entidade);
[color=red]at br.com.Testes.TesteConexao.main(TesteConexao.java:61)[/color] o erro arremete para a seguinte linha
livroDAO.salvar(l);
Quando utilizei o outro código, deu erro no q.list();

Aí me restou uma dúvida:
A classe ItemBibliotecaAutorPK deve estar lá no BD?
Será que o erro persiste por que a Classe ItemBiblioteca recebe 2 relacionamentos de N:1 e ainda um de N:N? E na hora de cadastrar, preciso pegar o codigo da editora e da seção que está a obra!
E aí o que faço? :shock:

Hebert_Coelho

Olha a mensagem do erro: Illegal attempt to associate a collection with two open sessions

Em algum lugar você está deixando a conexão aberta.
Sempre que você abrir uma conexão, feche logo em seguida.

Jackye

Olá, jakefrog!

Abri uma Session no seguinte código:
public static void main(String[] args) {
      
       Session secao = HibernateUtil.getSessionFactory().openSession();
        
        
        Editora editora = (Editora) secao.load(Editora.class, 2);
        Secao s = (Secao) secao.load(Secao.class, 2);
        Criteria criteria = secao.createCriteria(Autor.class);  
             Collection<Autor> a = (Collection<Autor>) criteria.list();    

        LivroDAO livroDAO = new LivroDAO();
        Livro l =  new Livro();
        
        l.setCodItemBiblioteca(11);
        l.setCodEditora(editora);
        l.setCodSecao(s);
        l.setCodAutor(a);
        l.setTitulo("Capitu");
        l.setNuReferencia(23424234);
        l.setEdicao(2);
        l.setAnoEdicao(1990);
        l.setNumeroExemplar(9);
        l.setVolume(1);
        l.setIsbn(234578);
        l.setDataCadastro(new Date());   
        
        livroDAO.salvar(l);         
    }
Onde e como insiro o código para fechar? Veja o código do GenericHibernateDAO:
package br.com.Persistencia;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;

public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, ID> {
    
    private Class<T> entidadePersistente;
    private Session sessao;
 
    public GenericHibernateDAO() {
        this.entidadePersistente = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
 
    @SuppressWarnings("unchecked")
    public void setSession(Session s) {
        this.sessao = s;
    }
 
    protected Session getSession() {
        if (sessao == null)
            sessao = HibernateUtil.getSessionFactory().openSession();
        else
            if (!sessao.isOpen())
                sessao = HibernateUtil.getSessionFactory().openSession();
        return sessao;
    }
 
    public Class<T> getEntidadePersistente() {
        return entidadePersistente;
    }
 
    //@SuppressWarnings("unchecked")
    @Override
    public T findById(ID id) {
        T entidade = (T) getSession().load(getEntidadePersistente(), id);
        return entidade;
    }
 
    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll() {      
        return findByCriteria();
    }
 
    @SuppressWarnings("unchecked")
    @Override
    public T salvar(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().save(entidade);
        transacao.commit();
        getSession().close(); 
        return entidade;
    }
 
    @Override
    public void remover(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().delete(entidade);
        transacao.commit();
        getSession().close(); 
    }
    
    @Override
    public void atualizar(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().saveOrUpdate(entidade);
        transacao.commit();
        getSession().close(); 
    }    
 
    public void flush() {
        getSession().flush();
    }
 
    public void clear() {
        getSession().clear();
    }
 
    /**
     * Use this inside subclasses as a convenience method.
     */
    @SuppressWarnings("unchecked")
    protected List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = getSession().createCriteria(getEntidadePersistente());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }
}
Criado 15 de dezembro de 2011
Ultima resposta 21 de dez. de 2011
Respostas 18
Participantes 3