Hibernate: como mapear três chaves primárias?

Boas.

Eu estou usar uma tabela que tem três chaves primárias.
O problema é que não sei como mapear três chaves primárias. Pelo que li isto deve ficar +/- assim:

<composite-id name = "id" class="go.action.Tipo_Util_Opcao"> <key-property name="aplicacao" type="java.lang.String" column="aplicacao" length="15"/> <key-property name="utiliz_tip" type="java.lang.String" column="utiliz_tip" length="10"/> <key-property name="opcao" type="java.lang.String" column="opcao" length="15"/> </composite-id>

O problema é que quando digo <composite-id name = "id" class="go.action.Tipo_Util_Opcao"> o compilador assume que tenho na minha tabela um campo “id” e dá erro porque nao encontra o POJO referente a essa variável…

O que estou a fazer mal?

Obrigado pela ajuda.

olá, mano…

você poderia passar a codificação da classe que criou e o mapeamento dela pro hibernate? Assim fica melhor de te dar resposta compreensível.

valeu

“O meu socorro vem do Senhor, que fez os céus e a Terra.”

Ok.

Aqui está a classe:

[code]package accessum.action;

import java.io.Serializable;

public class Tipo_Util_Opcao implements Serializable {

String aplicacao;
String utiliz_tip;
String opcao;

public Tipo_Util_Opcao(String aplicacao, String utiliz_tip, String opcao) {
	
	this.aplicacao = aplicacao;
	this.utiliz_tip = utiliz_tip;
	this.opcao = opcao;
}

public String getAplicacao() {
	return aplicacao;
}
public void setAplicacao(String aplicacao) {
	this.aplicacao = aplicacao;
}
public String getOpcao() {
	return opcao;
}
public void setOpcao(String opcao) {
	this.opcao = opcao;
}
public String getUtiliz_tip() {
	return utiliz_tip;
}
public void setUtiliz_tip(String utiliz_tip) {
	this.utiliz_tip = utiliz_tip;
}

}
[/code]

O mapeamento está aqui:

[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping default-lazy="false">

&lt;class  name=&quot;accessum.action.Tipo_Util_Opcao&quot;  table=&quot;tipo_util_opcao&quot; &gt;

&lt;composite-id name = &quot;id&quot; class=&quot;accessum.action.Tipo_Util_Opcao&quot; &gt;
	&lt;meta attribute=&quot;fiel-description&quot; inherit=&quot;false&quot;&gt;&lt;/meta&gt;
	&lt;key-property name=&quot;aplicacao&quot; type=&quot;java.lang.String&quot; column=&quot;aplicacao&quot; length=&quot;15&quot;/&gt;
 	&lt;key-property name=&quot;utiliz_tip&quot; type=&quot;java.lang.String&quot; column=&quot;utiliz_tip&quot; length=&quot;10&quot;/&gt;
	&lt;key-property name=&quot;opcao&quot; type=&quot;java.lang.String&quot; column=&quot;opcao&quot; length=&quot;15&quot;/&gt;
&lt;/composite-id&gt;

</class>
</hibernate-mapping>
[/code]

As 3 variáveis são chaves primárias.
Obrigado pela ajuda desde já.[/code]

Quando se trabalha com chave primária composta, o Hibernate precisa
de mais uma classe auxiliar para definir essa chave primária

Assim sendo, crie uma interface chamada PrimaryKey

public class PrimaryKey &#123;
  
  public Object getKey&#40;&#41;;

  public void setKey&#40;Object obj&#41;;

&#125;

Vamos fazer um pequeno exemplo: uma classe Pessoa que tem os seguintes atributos: cpf, rg, sexo , nome e data de nascimento. Suas chaves primárias são cpf e rg(só exemplo!!!)

código da chave primária:

public class PessoaPrimaryKey implements PrimaryKey, Serializable  &#123;
  private String cpf; //metodos get e set omitidos
  private String rg; //metodos get e set omitidos

  public Object getKey&#40;&#41; &#123;
    return this;
  &#125;

  public void setKey&#40;Object obj&#41; &#123;
    if &#40;obj instanceof PessoaPrimaryKey&#41; &#123;
       PessoaPrimaryKey pk = &#40;PessoaPrimaryKey&#41; obj;
       this.setCpf&#40;pk.getCpf&#40;&#41;&#41;;
       this.setRg&#40;pk.getRg&#40;&#41;&#41;;
    &#125;
  &#125;  

  /*Não esquece de implementar equals e hasCode*/

&#125;

Código da classe Pessoa:

public class Pessoa implements Serializable &#123;
   private String cpf;
   private String rg;
   private String sexo;
   private String nome;
   private java.util.Date dataNasc;
   private PessoaPrimaryKey pessoaPK;

   //metodos get set omitidos

   /*Não esquece de implementar equals e hasCode*/

&#125;

Feito isso, lá no mapeamento do hibernate, essa classe exemplo fica assim:

&lt;class  name=&quot;exemplo.Pessoa&quot;  table=&quot;tabela_pessoa&quot; &gt; 
    &lt;composite-id name = &quot;pessoaPK&quot; class=&quot;exemplo.PessoaPrimaryKey&quot; &gt;        
       &lt;key-property name=&quot;cpf&quot; type=&quot;java.lang.String&quot; column=&quot;cpf&quot; /&gt; 
       &lt;key-property name=&quot;rg&quot; type=&quot;java.lang.String&quot; column=&quot;rg&quot; /&gt;       
    &lt;/composite-id&gt; 
    &lt;property name=&quot;sexo&quot; type=&quot;java.lang.String&quot; column=&quot;sexo&quot; /&gt;
    &lt;property name=&quot;nome&quot; type=&quot;java.lang.String&quot; column=&quot;nome&quot; /&gt;
    &lt;property name=&quot;dataNasc&quot; type=&quot;java.util.Date&quot; column=&quot;dataNasc&quot; /&gt;               
&lt;/class&gt; 

Espero que esse exemplo te ajude na compreensão. Só um comentário: eu vi na documentação do Hibernate que o uso de composite-id é fortemente desaconselhável, mas cá pra nós, essa abordagem tá resolvendo um grande problema que eu tive de importação de grandes massas de dados usando persistência.

“Pela graça sois salvos por meio da fé, e isso não vem de vós, é dom de Deus”

só uma observação…essa recomendação do Hibernate para o não uso de chave composta, não apenas quando estamos utilizando o Hibernate…

em qq modelo de banco, chaves compostas devem ser usadas apenas em casos extremos…e também no caso de tabelas associativas em relacionamentos many-to-many…

flw