[RESOLVIDO] Dúvida mapeamento de herança de classes usando JPA

4 respostas
P

Boa tarde pessoal,

Estou com um problema para gerar o banco de dados de uma aplicação que estou fazendo usando JPA.
No meu exemplo eu tenho 3 classes: Pessoa, Professor e Disciplina. Professor herda de Pessoa e Disciplina está associado com professor em um relacionamento ManyToOne (Cada disciplina possui 1 único professor e um professor pode estar associado com N disciplinas)

Segue o código das classes usando as annotations do JPA.

Pessoa.java

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "pessoa")
@NamedQueries({
	@NamedQuery(name = "Pessoa.findByNome", query = "SELECT p FROM Pessoa p WHERE p.nome = :nome"),
	@NamedQuery(name = "Pessoa.findByIdade", query = "SELECT p FROM Pessoa p WHERE p.idade = :idade"),
	@NamedQuery(name = "Pessoa.findByRg", query = "SELECT p FROM Pessoa p WHERE p.rg = :rg"),
	@NamedQuery(name = "Pessoa.findByCpf", query = "SELECT p FROM Pessoa p WHERE p.cpf = :cpf"),
	@NamedQuery(name = "Pessoa.findByTelefone", query = "SELECT p FROM Pessoa p WHERE p.telefone = :telefone"),
        @NamedQuery(name = "Pessoa.findAll", query = "SELECT p FROM Pessoa p")})
public class Pessoa implements Serializable {

@Id
@Column(name = "CPF", nullable=false)
private String cpf;
@Basic(optional = false)
@Column(name = "NOME", nullable=false)
private String nome;
@Basic(optional = false)
@Column(name = "IDADE", nullable=false)
private int idade;
@Basic(optional = false)
@Column(name = "RG", nullable=false)
private String rg;
@Basic(optional = false)
@Column(name = "TELEFONE", nullable=true)
private String telefone;
.....

Professor.java

@Entity
@Table(name = "professor")
@NamedQueries({
	@NamedQuery(name = "Professor.findByFormacao", query = "SELECT p FROM Professor p WHERE p.formacao = :formacao"),
	@NamedQuery(name = "Professor.findByAreapesquisa", query = "SELECT p FROM Professor p WHERE p.areaPesquisa = :areaPesquisa"),
        @NamedQuery(name = "Professor.findAll", query = "SELECT p FROM Professor p")})
public class Professor extends Pessoa {

@Basic(optional = false)
@Column(name = "FORMACAO", nullable=true)
private String formacao;
@Basic(optional = false)
@Column(name = "AREAPESQUISA", nullable=false)
private String areaPesquisa;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "professor")
private Collection<Disciplina> disciplinas;
...

Disciplina.java

@Entity
@Table(name = "disciplina")
@NamedQueries({
	@NamedQuery(name = "Disciplina.findByQtdcreditos", query = "SELECT d FROM Disciplina d WHERE d.qtdCreditos = :qtdCreditos"),
	@NamedQuery(name = "Disciplina.findByNome", query = "SELECT d FROM Disciplina d WHERE d.nome = :nome"),
	@NamedQuery(name = "Disciplina.findByCodigo", query = "SELECT d FROM Disciplina d WHERE d.codigo = :codigo"),
	@NamedQuery(name = "Disciplina.findByCurso", query = "SELECT d FROM Disciplina d WHERE d.curso = :curso"),
	@NamedQuery(name = "Disciplina.findByProfessor", query = "SELECT d FROM Disciplina d WHERE d.professor = :professor"),
    @NamedQuery(name = "Disciplina.findAll", query = "SELECT d FROM Disciplina d")})
public class Disciplina implements Serializable {

@Basic(optional = false)
@Column(name = "QTDCREDITOS", nullable=true)
private int qtdCreditos;
@Basic(optional = false)
@Column(name = "NOME", nullable=false)
private String nome;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CODIGO", nullable=false)
private int codigo;
@JoinColumn(name = "CURSO_ID", referencedColumnName = "CODIGO")
@ManyToOne
private Curso curso;
@JoinColumn(name = "PROFESSOR_ID", referencedColumnName = "CPF")
@ManyToOne(optional = false)
private Professor professor;
...

Meu objetivo é que através da API JPA o banco de dados seja gerado corretamente. Porém, quando eu mando gerar o banco de dados, na tabela disciplina é criada uma chave estrangeira PROFESSOR_ID apontando para o campo CPF da tabela Pessoa, mas na verdade, deveria apontar para o campo CPF da tabela Professor (que herda de pessoa)

Alguém sabe se estou fazendo algo errado ou se existe um jeito de eu conseguir fazer eu referenciar a tabela professor ao invés da tabela pessoa nessa geração?

Ps: Estou usando Eclipse com EclipseLink 2.1 (JPA2)

Obrigado desde já…

4 Respostas

Kanin_Dragon

Jovem,

Você está gerando as ORM através do hibernate tools?

Para facilitar o entendimento post o DER do banco de dados ou os scripts de criação de tabela.

Abs,

P

oi amigo,

na verdade, não sei se vc entendeu… mas não estou partindo do banco de dados para gerar as entidades.
O que eu quero, na verdade, é fazer o contrário: a partir das entidades que eu escrevi eu desejo gerar as tabelas do banco de dados.

desta forma eu não tenho der ou scripts do banco, uma vez que é isso que eu desejo que a aplicação gere pra mim…

P

Pesquisando melhor mais pessoas tiveram o mesmo erro em:

http://java.net/jira/browse/GLASSFISH-2983
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1015
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2898

Alguém já viu esse erro? existe alguma maneira de contornar?

P

E ae pessoal,

Descobri o problema.

Apenas o JPA do HIBERNATE consegue fazer esse tipo de mapeamento corretamente.
Testei usando o EclipseLink, TopLink e Hibernate com o mesmo código no Netbeans 7… o hibernate foi o único que mapeou corretamente

Fica a dica para todos… prefiram sempre usar o hibernate…

Criado 14 de junho de 2011
Ultima resposta 16 de jun. de 2011
Respostas 4
Participantes 2