Mapear Chave Composta - Problema e Dúvida

9 respostas
R

Fala galera, boa tarde.

Esse é meu primeiro post aqui no forum, só estou recorrendo aqui pq não conseguí solucionar minha dúvida no tio google. Então vamos lá:

Tenho 3 tabelas.

Profissionais
MAT_PRO - PK

Indicadores
COD_IND - PK

Avaliacoes
COD_AVA - PK
MAT_PRO - PK FK
COD_IND - PK FK

Gostaria de saber como faço o mapeando da chave composta da tabela avaliacoes, pois acredito que isso resolveria meu problema.

Atualmente minhas classes AvaliacaoTO, ProfissionalTO e IndicadorTO se encontram da seguinte forma respectivamente abaixo. Estava tudo funcionando até me deparar com a seguinte situação:

Se na tabela Avaliacoes há registros do tipo:

Reg1
COD_AVA = 1
MAT_PRO = 1
COD_IND =1

Reg2
COD_AVA = 1
MAT_PRO = 1
COD_IND =2

Reg3
COD_AVA = 1
MAT_PRO = 1
COD_IND =3


E eu busco pelo COD_AVA = 1, ele deveria trazer esses 3 registros, certo? No entando, ele me traz o Reg1 três vezes!. Como resolver? :?:

@Entity
@Table(name="avaliacoes")
@NamedQueries(
		{ 
			@NamedQuery(name="avaliacoes.obterPorStatus", query="from AvaliacaoTO where status = :param")
		}
		)
public class AvaliacaoTO implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	@Id
	@Column(name="COD_AVA")
	private int codigo;
		
	@ManyToOne
	@JoinColumn(name="MAT_PRO", nullable=false) //Foreign Key
	private ProfissionalTO profissional;
	
	@ManyToOne
	@JoinColumn(name="COD_IND", nullable=false) //Foreign Key
	private IndicadorTO indicador;
@Entity
@Table(name="profissionais")
@NamedQueries(
		{ 
			@NamedQuery(name="profissionais.obterPorId", query="from ProfissionalTO where codigo = :param")
		}
		)
public class ProfissionalTO implements Serializable {
	
	private static final long serialVersionUID = 1L;

	@Id
	//@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="MAT_PRO")
	private Integer codigo;
	
	@OneToMany(mappedBy="profissional")
	private List<AvaliacaoTO> avaliacao;
@Entity
@Table(name="indicadores")
public class IndicadorTO implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="COD_IND")
	private int codigo;
	
	@OneToMany(mappedBy="indicador")
	private List<AvaliacaoTO>  avaliacao;

9 Respostas

R

A classe AvaliacaoTO foi definida com chave simples, não com chave composta. Da forma como a classe foi escrita, apenas o atributo codigo está sendo considerado na chave. Segue um exemplo de como definir a chave composta:

http://download.oracle.com/docs/cd/B32110_01/web.1013/b28221/cmp30cfg001.htm

R
roger_rf:
A classe AvaliacaoTO foi definida com chave simples, não com chave composta. Da forma como a classe foi escrita, apenas o atributo codigo está sendo considerado na chave. Segue um exemplo de como definir a chave composta:

[url]http://download.oracle.com/docs/cd/B32110_01/web.1013/b28221/cmp30cfg001.htm[/url]

Então no caso as minhas classes ficariam assim?

@Embeddable
public class AvaliacaoCK implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	@Column(name="COD_AVA")
	private int codigo;
	
	@ManyToOne
	@JoinColumn(name="MAT_PRO", nullable=false) //Foreign Key
	private ProfissionalTO profissional;
	
	@ManyToOne
	@JoinColumn(name="COD_IND", nullable=false) //Foreign Key
	private IndicadorTO indicador;
@Entity
@Table(name="avaliacoes")
@NamedQueries(
		{ 
			@NamedQuery(name="avaliacoes.obterPorStatus", query="from AvaliacaoTO where status = :param")
		}
		)
public class AvaliacaoTO implements Serializable {
	
	private static final long serialVersionUID = 1L;

	@EmbeddedId
	private AvaliacaoCK id;
@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="COD_IND")
	private int codigo;
	

	@OneToMany(mappedBy="indicador")
	private List<AvaliacaoCK>  avaliacao;
@Entity
@Table(name="profissionais")
@NamedQueries(
		{ 
			@NamedQuery(name="profissionais.obterPorId", query="from ProfissionalTO where codigo = :param")
		}
		)
public class ProfissionalTO implements Serializable {
	
	private static final long serialVersionUID = 1L;

	@Id
	//@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="MAT_PRO")
	private Integer codigo;
	
	
	@OneToMany(mappedBy="profissional")
	private List<AvaliacaoCK> avaliacao;
R

Não tenho um compilador à minha disposição para checar, mas acho que a sua modelagem deve funcionar desta vez.

R

Cara, trouxe os seguintes erros:

Exception created : java.lang.NoClassDefFoundError: com.brq.feedback.hibernate.HibernateUtil (initialization failure)

e

Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.brq.feedback.data.profissional.ProfissionalTO.avaliacao[com.brq.feedback.data.avaliacao.AvaliacaoCK]

Alguma idéia? Muito obrigado pela força, cara!!!

R

Os atributos avaliacao das classes IndicadorTO e ProfissionalTO devem ser do tipo AvaliacaoTO, não AvaliacaoCK.

A mensagem java.lang.NoClassDefFoundError: com.brq.feedback.hibernate.HibernateUtil (initialization failure) indica que algum ponto do seu código ou algum arquivo de configuração faz referência a uma classe chamada com.brq.feedback.hibernate.HibernateUtil, mas que esta classe não existe. Esta classe faz parte do código-fonte da sua aplicação ou está incluída em algum dos arquivos JAR do projeto?

R

Roger,

corrigí os atributos avaliacao das classes IndicadorTO e ProfissionalTO e recebí isso agora:

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.brq.feedback.data.avaliacao.AvaliacaoTO.profissional in com.brq.feedback.data.profissional.ProfissionalTO.avaliacao

Sim, essa classe faz parte do meu código-fonte. Esse erro só começou depois que mudei a chave do AvaliacaoTO, até antes disso tava ok. Acho q corrigindo o erro acima, consigo solucionar tudo.

Sugestão?

R

Roger,

resolví o problema com o seguinte:

na classe ProfissionalTO

@OneToMany(mappedBy="AvaliacaoCK.profissional") private List<AvaliacaoTO> avaliacao;

Porém o outro erro persiste, será q tenho q mapear o AvaliacaoCK no hibernate.cfg?

R

Acho que você vai conseguir resolver fazendo o seguinte na classe IndicadorTO:

@OneToMany(mappedBy="AvaliacaoCK.indicador")  
    private List<AvaliacaoTO> avaliacao;
R

Roger,

conseguí resolver!

O erro final era q mappedBy tinha q passar “id.profissional”, pois id era o nome do objeto no AvaliacaoTO. AvaliacaoCK era na verdade o tipo do objeto, por isso ele não estava encontrando! :smiley:

Muito obrigado pela força, se algum dia puder te ajudar, estamos ai!

RESOLVIDO!

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