[RESOLVIDO]Erro com a anotação @MappedSuperClass

6 respostas
B

Boa noite pessoal, tenho tres entidade, Pessoa, PessoaFisica e Pessoa Juridica, sendo que Pessoa é a classe pai abstrata e estou com o seguinte erro ao gravar dados no banco.

Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: br.com.testeheranca.entity.Endereco.pessoas[br.com.testeheranca.entity.Pessoa]
        at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1068)
        at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:600)
        at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:541)
        at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:43)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1130)
        at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:324)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
        at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
        at br.com.testeheranca.dao.HibernateUtil.<clinit>(HibernateUtil.java:25)
        ... 2 more
Java Result: 1

As tabelas são geradas corretamente pelo hibernate com as foreign keys e tal, mas quando tento persistir algum dado no banco gera esse erro.

minhas entidades

@MappedSuperclass
public abstract class Pessoa {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    @Column(name="nome", length=30, nullable=false)
    private String nome;
    @Column(name="descricao", length=50)
    private String descricao;

    @ManyToOne
    @JoinColumn(name="endereco", referencedColumnName="id", nullable=false)
    private Endereco endereco;

    public String getDescricao() {
        return descricao;
    }

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

    public int getId() {
        return id;
    }

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

    public String getNome() {
        return nome;
    }

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

    public Endereco getEndereco() {
        return endereco;
    }

    public void setEndereco(Endereco endereco) {
        this.endereco = endereco;
    }
    
}
@Entity
@Table(name="pessoa_fisica")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class PessoaFisica extends Pessoa implements Serializable {

    @Column(name="cpf", length=14, nullable=false)
    private String cpf;

    @AttributeOverrides({@AttributeOverride(name="endereco", column=@Column(name="endereco")),
    @AttributeOverride(name="nome", column=@Column(name="nome")),
    @AttributeOverride(name="descricao", column=@Column(name="descricao"))})

    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }    
}
@Entity
@Table(name="pessoa_juridica")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class PessoaJuridica extends Pessoa implements Serializable {

    @Column(name="cnpj", length=30)

    @AttributeOverrides({@AttributeOverride(name="endereco", column=@Column(name="endereco")),
    @AttributeOverride(name="nome", column=@Column(name="nome")), 
    @AttributeOverride(name="descricao", column=@Column(name="descricao"))})
    
    private String cnpj;

    public String getCnpj() {
        return cnpj;
    }

    public void setCnpj(String cnpj) {
        this.cnpj = cnpj;
    }    
}

Aqui o arquivo de configuração do hibernate

<?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/testerectfer</property>
    <property name="hibernate.connection.username">postgres</property>
    <mapping class="br.com.testeheranca.entity.Pessoa"/>
    <mapping class="br.com.testeheranca.entity.PessoaFisica"/>
    <mapping class="br.com.testeheranca.entity.PessoaJuridica"/>
    <mapping class="br.com.testeheranca.entity.Endereco"/>
  </session-factory>
</hibernate-configuration>

O persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="TesteHerancaComAnnotationsPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
     <properties>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.connection.username" value="postgres"/>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.connection.password" value="admpostgre"/>
      <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/testerectfer"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>

A classe Dao de teste

public class dao {

    private Session session;


    public void gravar(Pessoa pessoa) {
        session = HibernateUtil.getInstance();//inicia a sessão
        Transaction tx = null; //Permite realizar transações em um banco de dados
        try{
            tx = session.beginTransaction();//abre uma transação com o banco
            session.save(pessoa);//salva a cidade
            tx.commit();//A transação é efetuada através do método commit()
        }catch(HibernateException e){
            e.printStackTrace();
            tx.rollback();//desfaz a transação em caso de erro
        }finally{
            session.close();//fecha a sessão
        }
    }

    public void gravar(Endereco endereco) {
        session = HibernateUtil.getInstance();//inicia a sessão
        Transaction tx = null; //Permite realizar transações em um banco de dados
        try{
            tx = session.beginTransaction();//abre uma transação com o banco
            session.save(endereco);//salva a cidade
            tx.commit();//A transação é efetuada através do método commit()
        }catch(HibernateException e){
            e.printStackTrace();
            tx.rollback();//desfaz a transação em caso de erro
        }finally{
            session.close();//fecha a sessão
        }
    }

}

e a classe com o main pra fazer os testes de gravação no banco

public class teste {

    
    public static void main(String args[]){

      Pessoa fisica = new PessoaFisica();
      Pessoa juridica = new PessoaJuridica();
      Endereco end = new Endereco();

      end.setLogradouro("Fransisco murtinho");
      end.setBairro("Vila Velha");
      fisica.setEndereco(end);
      juridica.setEndereco(end);
      fisica.setNome("Paulo");
      juridica.setNome("Rogerio");
      fisica.setDescricao("tes");
      juridica.setDescricao("tes");
      end.setPessoas(fisica);
      end.setPessoas(juridica);
      dao d = new dao();
      d.gravar(end);
      d.gravar(fisica);
      d.gravar(juridica);

     
    }
}

Pesquisei em vários foruns sem sucesso, se alguém puder me ajudar agradeço muito.

6 Respostas

D

Vamos lá…
@MappedSuperclass não indica que a classe em questão é uma @Entity, logo, quando você possui referência à ela, onde quer que seja, você terá uma exception.
As tabelas são geradas de forma adequada pois o hibernate “olha” para aquelas classes que estão identificadas na configuração (ou são adicionadas ao objeto Configuration pelo addAnnotatedClass) e, também, estão anotadas com @Entity e possuem um @Id.

Este erro

Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: br.com.testeheranca.entity.Endereco.pessoas[br.com.testeheranca.entity.Pessoa]

Diz que você tem um relacionamento 1 : 1 ou 1 : N de Endereço para Pessoa, esta última não é uma entidade é apenas a @MappedSuperclass

B

Obrigado pela ajuda drsmachado, então para que possa persistir os dados em vez de indicar para a pessoa terei que fazer o relacionamento nas classes PessoaFisica e PessoaJuridica com o Endereco?

D

Exatamente. Embora isso possa causar problemas, pois, você está criando acoplamentos que, no modelo orientado a objetos, seriam desnecessários.

B

Pensei nisso também, mas desse jeito a herança não estará ajudando muito.
Há outra maneira de realizar este caso?/

D

A herança ajudaria se você a implementasse, também, no banco de dados, transformando a @MappedSuperclass em @Entity e, então, usando as anotações de herança, como para o @Id e @Inheritance.
Caso contrário, precisará desmembrar o modelo

B

Ta certo, desse jeito funcionou.
Obrigado drsmachado pela grande ajuda.
abraços

Criado 3 de julho de 2012
Ultima resposta 4 de jul. de 2012
Respostas 6
Participantes 2